2

It looks like on ATMega based boards, float and double are equivalent 32-bit (4-byte) data types.

However, on the Arduino Due, doubles are 64-bit (8-byte) where floats are 32-bit (4-byte), same as the ATMega boards.

I also saw one source on avr-gcc that listed double as non-standard.

So, when writing code for ATMega based boards are floats preferable to using doubles, since that would make the code equivalent for Due boards? Or are doubles preferable for any reason?

2
  • 2
    I would use float so that anyone reading my code, who may not know about the non-standard AVR double, knows what precision to expect. But this is more personal preference than a hard rule (hence I do not consider it a “real” answer). – Edgar Bonet Feb 12 '16 at 9:41
  • I think that's fairly solid reasoning; one might not expect the 'double' to really be a float if they're coming from another platform. – Ehryk Feb 12 '16 at 16:35
2

See avr-gcc

Deviations from the Standard

double

double is only 32 bits wide and implemented in the same way as float


when writing code for ATMega based boards ...

They are the same, therefore.


(Edited to add)

When writing code, is it then preferable to using one over the other?

I don't really understand your question. You asked about writing code for the ATMega based boards. Do you really mean, if you are writing code for the Due? The quick answer would be, on the Due, double takes twice the RAM, however it is over twice as precise - around 7.2 decimal digits for float compared to 15.9 for double. (I'm not sure about the speed, probably double would be slower, unless it is implemented in floating-point hardware - however I cannot see any reference to that on the AT91SAM3X8E datasheet).

See: https://en.wikipedia.org/wiki/Floating_point

If you want more precision (however slower and taking more RAM) then you could use double - which won't make any difference on the ATmega based boards, but will on the Due.


As Edgar Bonet said:

I would use float so that anyone reading my code, who may not know about the non-standard AVR double, knows what precision to expect.

That makes quite a bit of sense.


I warn you though that "preferable" is subjective. It is close to asking "what is best"? To which the reply is: "best for what?"

6
  • On ATMega boards, yes, they are the same. If you then take the code to an Arduino Due, they are no longer the same if using double, but the same if using float. When writing code, is it then preferable to using one over the other? Why or why not? – Ehryk Feb 12 '16 at 16:30
  • See amended reply. – Nick Gammon Feb 12 '16 at 20:19
  • Well, strictly speaking I'm only targeting ATMega architectures right now, I thought I was writing code that was consistent across all arduinos. I did not ask which was best, though I think I'm answering my own question in that float is more well known, a better cross-architecture description of the datatype, and consistent across more arduinos. – Ehryk Feb 14 '16 at 5:43
  • Would it make more sense if I added "When writing Arduino code for an unknown board, is it then preferable to use one over the other?" – Ehryk Feb 14 '16 at 5:46
  • I suppose. *shrug* - when dealing with boards which may have limited RAM and Flash, it isn't always possible to code generically. – Nick Gammon Feb 14 '16 at 5:55
1

Neither are preferable.

Unless your microcontroller has a hardware floating point unit using float or double results in huge overheads for your program.

So instead use integer mathematics whenever possible.

Instead of working in Volts, work in millivolts, for example.

However, if your MCU does have an FPU, and some modern more powerful ones do, then you should use the size of float or double that is native to the FPU. If it is a 32 bit FPU then use float. If it is a 64 bit FPU then you can use double.

8
  • do you have any actual benchmarks of the "huge overheads"? less efficient sure, but I've never really had it be a problem to use floating point on arduino. – BrettAM Feb 12 '16 at 17:34
  • 1
    int a; void setup() { a = 1; } void loop() { a = a * 2; } uses 482 bytes. Change the int to a float it slmost doubles to 878 bytes. Even worse if you change the 2 to 2.0, while it's int - you end up with 1086 bytes. Massive increases. And that's not even mentioning how long it takes to run. I'll do a crude benchmark. – Majenko Feb 12 '16 at 18:42
  • 1
    Multiplying 1 by 2 until it exceeds 32768 (1, 2, 4, 8, 16, etc) with int takes 12 microseconds. Using float it takes 148 microseconds. That's more than ten times longer for just that one simple operation. – Majenko Feb 12 '16 at 18:48
  • Interestingly, multiplying an integer by 2.0 takes even longer - 208 microseconds. 17 times longer. – Majenko Feb 12 '16 at 18:50
  • Fixed point takes more ops than just integer multiply, and we should be comparing 32-bit values on both sides. in a test of float (a*b) and long (a*b/1000), as would be the case if you did operations in mV, floating point is faster. That's not calculating the extra high byte that's necessary for real fixed point, then again fixed point would benefit from an easier divisor. Addition will certainly remain faster in fixed point. I don't think float vs fixed is as clear cut as the arduino SE community makes it out to be. – BrettAM Feb 13 '16 at 1:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.