Pages: [1]   Go Down
Author Topic: printing floats without the leading '0' on fractional results  (Read 626 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 289
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am sending values to Serial.print in the format:

Code:
Serial.print(Integer result);
Serial.println(fractional result);

So the number 40.43567 would be printed as:

Code:
Serial.print("40");
Serial.print(".43567");

but the numbers are represented by variables.  I am doing this to get more precision out of the float data type, peeling off the integer value and then calculating the fractional separately before combining them in my output for viewing.  The problem is that printing floats that are a fractional amount seems to be placing a zero in front of the decimal so:

Code:
.43567 gets printed as
0.43567

which means my output based on the two calls to Serial.print would look like:

Code:
400.43567

Is there a way to make it not print that leading zero on the fractional value?
Logged

Arduino Uno;
Mega328

Finland
Offline Offline
Jr. Member
**
Karma: 1
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can use dtostrf function to get the float into a string.
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42

Then, if the original float is in between 0 and 1, you trim one character from the left, the zero, out. Or trim all character to the left of the decimal separator out.

I'll have to study how do you manipulate strings with Arduino, but how is this for a start?

Edit: Maybe I read that too quickly. I don't understand the input values in your case. If you had the integer and fraction as wholes, you could just combine them into a string, separated with a dot. But if you insist on having the fractional part in a float, the above is something I would look into except the fractional should always be greater or equal to zero and smaller than 1. If I understood the setup correctly.
« Last Edit: January 21, 2013, 02:04:53 pm by Chaul » Logged

0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 289
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can use dtostrf function to get the float into a string.
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42

Then, if the original float is in between 0 and 1, you trim one character from the left, the zero, out. Or trim all character to the left of the decimal separator out.

I'll have to study how do you manipulate strings with Arduino, but how is this for a start?

That's a good place to start and looks easy to implement.  Thanks!
Logged

Arduino Uno;
Mega328

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12631
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So the number 40.43567 would be printed as:

Code:
Serial.print("40");
Serial.print(".43567");

Is there some reason you don't just use this?
Code:
Serial.print(40.43567, 5);
Logged

I only provide help via the forum - please do not contact me for private consultancy.

0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 289
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The project is a GPS logger and I notice when I pick a spot on google maps it shows the GPS coordinates with 6 digits after the decimal point so for instance, the U.S. Post Office in my town is located at GPS coordinates:

Code:
40.666585,-74.115669

according to google maps.  I would like to be able to calculate to that same degree of precision with my GPS module but as I understand, arduino floats/doubles can only handle about 6-7 total digits which would mean 2-3 digits for the integer portion and 3 - 4 digits in the fractional portion.
Logged

Arduino Uno;
Mega328

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12631
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would like to be able to calculate to that same degree of precision with my GPS module

In that case you can't use floats or doubles. You could use fixed point arithmetic and 32-bit (or 64-bit, if necessary to get the range you need) ints to hold the values.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 289
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well that is why I was hoping to be able to break it up into chunks and handle each separately so for instance the data comes in from the GPS as something like:

GPGGA,175030.000,4041.1314,N,07406.5125,W,1,07,1.2,-189.2,M,-34.2,M,,0000*4D

with 4041.1314 being the latitude written as 40 degrees, 41.1314 minutes N latitude.  My sketch pulls out the 4041 and the 1314 as separate numbers.  I then divide the 4041 by 100 to get 40.41 and take just the integer (40) portion as my degrees and then subtract out that integer from the 40.41, multiply it by 100 to get 41 minutes.  Then I add the 41 minutes to the .1314 to get 41.1314 and divide by 60 to get the fractional amount of degrees.  Now it seems to me that I should be able to divide a float value of 41.1314 by 60 and get 6 significant digits because at no time should a float have to truncate any of those values.  Then I can print out the integer degrees value of 40 and then the fractional result from the 41.1314/60 calculation and all should be well.  What am I missing here?
Logged

Arduino Uno;
Mega328

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12631
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What am I missing here?

If you're trying to get the angle as a floating point value in degrees, you could just add the integer part (41 in your example) and the fractional part (0.68552...) as float values to get 41.68552... to as many decimal places as float supports and print that. If you need better precision than float supports then you're back to using fixed point arithmetic as suggested previously.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7197
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

About that 6 digit google gps coordinate, I stared at it sometime back and suspected it is just software engineers not knowing what a gps can do. I was right:

http://wiki.xkcd.com/geohashing/GPS_accuracy

I think getring 5 digits is already asking a bit too much;) 6 digits will be asking for 10 centimeter accuracy. Not sure if millitary can get that good.
Logged


0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 289
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

About that 6 digit google gps coordinate, I stared at it sometime back and suspected it is just software engineers not knowing what a gps can do. I was right:

http://wiki.xkcd.com/geohashing/GPS_accuracy

I think getring 5 digits is already asking a bit too much;) 6 digits will be asking for 10 centimeter accuracy. Not sure if millitary can get that good.

Good to know!  I started working out the numbers and began to realize that even where the GPS is off a bit, it is consistently off by that amount (usually only a few yards), and since I am calculating distances, the relative distances between two points should be accurate.
Logged

Arduino Uno;
Mega328

Pages: [1]   Go Up
Jump to: