The following code:
Serial.println(cipheredcharacter);
Serial.print((int)cipheredcharacter);
Print this:
52.00
51
It's probably the 8 bit limit of the ATMega 328 chip that makes the conversion so inaccurate, anyone know any workaround ?
The following code:
Serial.println(cipheredcharacter);
Serial.print((int)cipheredcharacter);
Print this:
52.00
51
It's probably the 8 bit limit of the ATMega 328 chip that makes the conversion so inaccurate, anyone know any workaround ?
It's probably the 8 bit limit of the ATMega 328 chip that makes the conversion so inaccurate
Give over.
It is the fact that floats round up and ints truncate. Happens on all implementations of C. And most other languages.
There still a huge range of methods that can do this properly, but with 8 bits it also needs a pair of registers, I programmed a while in assembly for the ATMega 328, what a painful thing was using floating points, anyway I think I'm in a dead end cause:
I use pow for calculating a bit value so I can't put the result in a integer cause will result in accuracy loss, but I need to convert this float to a character! In the conversion to character I got the problem, I presumed a ASCII table problem but to make sure I tested the conversion by printing the same variable with different casts, then I found this dead end.
I use pow for calculating a bit value so I can't put the result in a integer cause will result in accuracy loss, but
You loose accuracy whenever you use a floating point number. Why not use a long long, this gives you a 64 bit number.
There is no effect of 8 bit or 16 bit or 32 bit machine on the accuracy of the number representation it is down to the way the numbers are represented.
It's 16 bit dude, the ATMega328 memory is divided by 16bit 1Kx16bits and the registers are 8 bits wide, with a 8 bit word, then to store and manipulate floating points it uses a pair of registers.
I read once that working with floats is like moving piles of sand from one pile to another, you always lose some of the grains.
Lefty
I studied a lot of computer architecture I know really fine the whole thing, the method could be more accurate but facing the ATMega328 low frequency maybe a low accurate method suits better, anyway I made my own pow method that uses ints.
Printing a float presumably rounds properly.
Assigning a float to an int causes truncation.
So if "a" is "51.99972", printing it will yield "52", and assigning it to an int will yield "51."
Do your own rounding:
Serial.print((int)(cipheredcharacter+0.5));
gabrielgarcia:
I studied a lot of computer architecture I know really fine the whole thing, the method could be more accurate but facing the ATMega328 low frequency maybe a low accurate method suits better,
the architecture has absoloutly nothing to do with the accuracy nor does the speed. It is all downto the software in the compiler.
A floating point representation uses a binary fraction and some numbers are hard to represent like this. This applies to any number base, for example in the base 10 there are numbers that result in recurring decimals, those same numbers can be expressed more accurately in other number bases.
Grumpy_Mike:
gabrielgarcia:
I studied a lot of computer architecture I know really fine the whole thing, the method could be more accurate but facing the ATMega328 low frequency maybe a low accurate method suits better,the architecture has absolutely nothing to do with the accuracy nor does the speed. It is all down to the software in the compiler.
A floating point representation uses a binary fraction and some numbers are hard to represent like this. This applies to any number base, for example in the base 10 there are numbers that result in recurring decimals, those same numbers can be expressed more accurately in other number bases.
Good simple example - two thirds. Can be represented precisely as a fraction - 2/3, but can't be represented in decimal as it's recurring - 0.6666666... With rounding to fit in a specific number of (e.g., two) decimal places that becomes 0.67.
It has nothing at all to do with the method used to convert or round, it's a simple fact that it cannot be represented precisely in the given space. In fact, in decimal, it cannot be represented precisely at all in the known universe - there isn't enough room to write all the digits.
It's a case of it being "accurate enough" for most simple purposes.
If you need to retain a known accuracy level you won't be using floats - you'll be using scaled integer math. For instance, instead of working with volts (0.4, 1.763, 4.993) work with millivolts (400, 1763, 4993) as integer values. Instead of seconds (173.298) work with milliseconds (173298) or microseconds (173298000) in suitably sized integer variables. That way your accuracy is known and predictable.
Alan has a very good read on Arduino/AVR-GCC math in this article:
http://bleaklow.com/2012/06/20/sensor_smoothing_and_optimised_maths_on_the_arduino.html
And some interesting work-arounds. Worth the 5 minutes to read.
Ray
I read once that working with floats is like moving piles of sand from one pile to another, you always lose some of the grains.
...and also pick up some dirt.
AWOL:
I read once that working with floats is like moving piles of sand from one pile to another, you always lose some of the grains.
...and also pick up some dirt.
And the odd worm.