I tried to print out a big double like 2E20 and serial print didn't convert to E format, it just gave me an overflow. Is this a bug or do I need to set a flag somewhere?
says:-
on the Arduino, double is the same size as float.
2E20 and serial print didn't convert to E format, it just gave me an overflow.
Try 2.0E20
Read
My text was too short. I wrote a program that multiplied 2.0 by tens i.e. 2.010.0, 2.0100.0 etc. and after 2.0e9 I get the overflow message ovf instead of 2.0e10. It is Serial.print or a setting needs to be changed. I don't think it can print in e format.
wmassano:
My text was too short. I wrote a program that multiplied 2.0 by tens i.e. 2.010.0, 2.0100.0 etc. and after 2.0e9 I get the overflow message ovf instead of 2.0e10. It is Serial.print or a setting needs to be changed. I don't think it can print in e format.
Did you read that page? it says:-
Floating-point numbers can be as large as 3.4028235E+38 and as low as -3.4028235E+38.
So you blew up the floating point limit with a value of E45
2.0E9 is less than 3.0E38. I am not getting an overflow on the variable. I can use it. I just can't print it!
Try this and see for yourself
int i;
double test=2.0;
void setup(){
Serial.begin(9600);
for(i=1;i<20;i++){
test=test*10.0;
Serial.print("test= ");
Serial.println(test);
}
}
void loop(){
}
It will blow long befor you reach 2E20 which is STILL less than E38 !
wmassano:
2.0E9 is less than 3.0E38. I am not getting an overflow on the variable. I can use it. I just can't print it!
Try this and see for yourselfint i;
double test=2.0;void setup(){
Serial.begin(9600);
for(i=1;i<20;i++){
test=test*10.0;
Serial.print("test= ");
Serial.println(test);
}
}
void loop(){
}It will blow long befor you reach 2E20 which is STILL less than E38 !
test= 20.00
test= 200.00
test= 2000.00
test= 20000.00
test= 200000.00
test= 2000000.00
test= 20000000.00
test= 200000000.00
test= 2000000000.00
test= ovf
test= ovf
test= ovf
test= ovf
test= ovf
test= ovf
test= ovf
test= ovf
test= ovf
test= ovf
Here's what I get (of course I'm using MY Print library that isn't full of bugs......)
Ok try this:-
http://forum.arduino.cc/index.php/topic,44216.0.html#13
Grumpy_Mike:
Ok try this:-
http://forum.arduino.cc/index.php/topic,44216.0.html#13
You know since doubles and floats are only 8 bytes, you can't get E38 precision.
Even within Print,cpp, there is code to print "ovf" if the float number is larger than 4294967040.0 or smaller than -4294967040.0.
You can't squeeze more "precision" out of 8 bytes.
You know since doubles and floats are only 8 bytes, you can't get E38 precision.
Wrong on two counts.
Floats are four bytes not eight and you can get E32 out of four bytes if you have five BITS reserved for the exponent.
I think you are missing the point. I am not looking for more decimal places. I am looking for the printing to be like "normal" C that when the exponent is too big, it prints the numbers as 2.0E15 etc. it should not say overflow when the number is a valid float. I don't think Serial.print is capable of E format and that is a flaw.
Grumpy_Mike:
You know since doubles and floats are only 8 bytes, you can't get E38 precision.
Wrong on two counts.
Floats are four bytes not eight and you can get E32 out of four bytes if you have five BITS reserved for the exponent.
I knew that (4 bytes). I mistyped.
As far as how floats are handled by the AVRGCC libraries, it seems as though there is a limit ROUGHLY equivalent to +/- 2E32 (that is, plus or minus 4294967040.0) which is quite close to 2E32 (4294967296).
wmassano:
I think you are missing the point. I am not looking for more decimal places. I am looking for the printing to be like "normal" C that when the exponent is too big, it prints the numbers as 2.0E15 etc. it should not say overflow when the number is a valid float. I don't think Serial.print is capable of E format and that is a flaw.
You are right. The code "Print.cpp" does this for floats:
size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
n += print(toPrint);
remainder -= toPrint;
}
return n;
}
Let me try something though........ I maye have THE solution to your problem.......
As regards to 8 byte floats, the exponent in that case should be in the hundreds (308 I think) in most languages, but it is not an issue with the numbers, it is with the printing. I can export a number like 2.0E20 from the Arduino to a TI84 and it comes across correctly. The Serial.print command doesn't know what to do with it.
Maybe I just landed on a different planet, but 2E32 is 2 followed by 32 zeros, not 2^32 !
wmassano:
I am looking for the printing to be like "normal" C that when the exponent is too big
Arduino is normal C. What you mean is" like libc's stdio.h", which Arduino doesn't use.
wmassano:
I don't think Serial.print is capable of E format and that is a flaw.
Missing functionality is more appropriate. It isn't like there is a bug preventing it from happening, print() wasn't designed to print scientific format. Expecting to do so is the flaw.
The function from Mike's link gets you what you want.
wmassano:
I think you are missing the point. I am not looking for more decimal places. I am looking for the printing to be like "normal" C that when the exponent is too big, it prints the numbers as 2.0E15 etc. it should not say overflow when the number is a valid float. I don't think Serial.print is capable of E format and that is a flaw.
OK I edited your code and got this:
test= 2.00, e=0
test= 20.00, e=1
test= 200.00, e=2
test= 2000.00, e=3
test= 20000.00, e=4
test= 200000.00, e=5
test= 2000000.00, e=6
test= 20000000.00, e=7
test= 200000000.00, e=8
test= 2000000000.00, e=9
test= 20000000000.00, e=10
test= 200000000000.00, e=11
test= 2000000000000.00, e=12
test= 20000000000000.00, e=13
test= 200000000000000.00, e=14
test= 2000000000000000.00, e=15
test= 20000001000000000.00, e=16
test= 200000000000000000.00, e=17
test= 2000000000000000000.00, e=18
test= 20000000000000000000.00, e=19
test= 200000000000000000000.00, e=20
test= 2000000000000000000000.00, e=21
test= 20000000000000000000000.00, e=22
test= 200000000000000000000000.00, e=23
test= 2000000000000000000000000.00, e=24
test= 20000001000000000000000000.00, e=25
test= 200000010000000000000000000.00, e=26
test= 2000000100000000000000000000.00, e=27
test= 20000001000000000000000000000.00, e=28
test= 200000000000000000000000000000.00, e=29
test= 2000000000000000000000000000000.00, e=30
test= 20000000000000000000000000000000.00, e=31
test= 200000010000000000000000000000000.00, e=32
test= 2000000100000000000000000000000000.00, e=33
test= 20000001000000000000000000000000000.00, e=34
test= 200000010000000000000000000000000000.00, e=35
test= 2000000100000000000000000000000000000.00, e=36
test= 20000001000000000000000000000000000000.00, e=37
test= 200000010000000000000000000000000000000.00, e=38
test= inf, e=39
This is what I did:
int i;
double test=2.0;
char buffer [128];
void setup(){
Serial.begin(115200);
for(i=0;i<40;i++){
sprintf (buffer, "test= %.2f, e=%u\r\n", test, i);
Serial.print (buffer);
test=test*10.0;
}
}
void loop(){
}
If you like, I can provide you with an edited file "pde.jar" which adds an option to Preferences, allowing you to enable floating point support (for code like above) at the expense of your sketch being a few KB larger, or turn it off to revert to no floating point support (the way the Arduino IDE is). If you want it, what IDE are you using? (Version)?
wmassano:
As regards to 8 byte floats, the exponent in that case should be in the hundreds (308 I think) in most languages, but it is not an issue with the numbers, it is with the printing. I can export a number like 2.0E20 from the Arduino to a TI84 and it comes across correctly. The Serial.print command doesn't know what to do with it.
I mistyped. Arduino floats (and doubles) are 4 bytes, not 8.
I disagree. (This could turn into a semantics mess if we are not careful). The print function should handle any valid value in C. To limit the output to about 2x10^9 is a serious shortcoming, and completely unexpected. They do so much so well this seems like a bug rather than a design decision.As to mike's code, the code I saw doesn't address the problem. Since we are using effectively a C++ style of print (no format string) the transition should be seemless. I assume this will happen at the other end. Suppose you are using the arduino to measure the capacitance. It is incapable of printing out picofarads as 10^-12. It takes so much from the arv lib, why can't they get the print functionality???
I didn't see the code you were referring to until after I posted, but it is nstill a kludge tht doesn't address the problem. I could write my own routine to do it right, but I still think they should fix this
wmassano:
I disagree. (This could turn into a semantics mess if we are not careful). The print function should handle any valid value in C.
Not semantics. Possibly pedantics. printf() is defined, print() is not.
It's clear you're upset, however, this is how the Arduino libraries chose to implement print(). All code and implementations have trade-offs, and those trade-offs will eventually upset someone. I'm not sure loudly disagreeing is going to get much done to fix it. At the very least, you need to take your comments to the developer-mailing list.
wmassano:
Since we are using effectively a C++ style of print (no format string)
Again, I'm not aware of a standards-defined print() function.
wmassano:
It takes so much from the arv lib, why can't they get the print functionality???
avr-libc does have some limitations when it comes to printf() and sprintf(). For example, by default, it does not support printing floats.