Strange behaviour with the Sum of Floats

Hello,

I'm having trouble with adding floats. I know that float values can be unpredictable but i think i'm doing something wrong here.
I'm trying to calculate the julian day with the following calculation:

float julian = ((float)t / (float)86400) + (float)2440587.5;
where t is the current time in seconds.

When i do "1451231908 / 86400" i get 16796.666015 (which is about right);
But when i add 2440587.5 i constantly get 2457384.2500000. The correct answer would be something like: 2457384.1656018

What am i doing wrong?

Thanks in advance

Peter

What am i doing wrong?

You have unrealistic expectations. A float, on the Arduino, has 6 to 7 digits of precision. How many digits are involved in your numbers? 8 or more.

6 digits of precision is fine.
But what i'm asking is why is the outcome always the same: 2457384.25 when the time input is different,
instead of at least something like: 2457384.16

What am i doing wrong?

You're not showing us your code.

2457384 - that's seven digits right there.

This is the code t is time in seconds (now()).

// get JulianDate
float MoonPhase::jtime(long t)
{
   Serial.println((float)t / (float)86400, 6);
   Serial.println((float)t / (float)86400 + (float)2440587.5, 6);
   float julian = ((float)t / (float)86400) + (float)2440587.5; 
   return julian;
}

2440587.5 has 8 digits.

Ahh.. now i get it.

Thanks!

For astronomical calculations there are a few tricks to get around this digit limitation (with reduced accuracy). If you will tell us what you want to do, we might be able to suggest some code that is optimized for the Arduino.

peterv3210:
But when i add 2440587.5 i constantly get 2457384.2500000. The correct answer would be something like: 2457384.1656018

What am i doing wrong?

2457384.xxxx = 7 significant digits

Everything after the decimal point is pure imagination.

If you want to do more accurate calculations using an Arduino, DO NOT use 'float' as a variable type.
Float is accurate up to 7 significant digits at most (sometimes only 6).

But "long" is accurate up to 9 digits.

If you need even higher accuracy, let's say with date and time, you can use:

  • long for "Julian Day Number"
  • long for "fraction of a day", i.e. "seconds past midnight", or "milliseconds past midnight" for even higher accuracy.

I’m trying to calculate the current percentage of the moon phase with the attached file.
It’s a converted php script which i found (a long time ago) on the internet. So i don’t know who to give credits for it.

So i think i have to divide everything by 2 to get smaller numbers.

moonphase.cpp (5.11 KB)

moonphase.h (318 Bytes)

Here is an Arduino moon phase function, which uses long variables for Julian Day, etc.

I haven't tested it for accuracy.

jremington:
Here is an Arduino moon phase function, which uses long variables for Julian Day, etc.

I haven't tested it for accuracy.

This function calculates the moon phase by day i need it at least per 15 min.

peterv3210:
This function calculates the moon phase by day i need it at least per 15 min.

The moon rotates faster around your planet?

:slight_smile:

peterv3210:
I'm trying to calculate the current percentage of the moon phase with the attached file.

For what reason?
Do you need high accuracy?

If you'd need high accuracy for astronomical applications, it would be perhaps the best idea to calculate the numbers on a number-crunching processor, perhaps a PC, and then retrieve calculated data (perhaps a table of the month or a table of the day) from the PC.

There are also astronomy websites on the Internet which provide highly accurate data tables, so if you'd use an Ethernet Shield with your Arduino, you possibly could just retrieve calculated high-precision table data from the Internet, when you need them.

I'm trying to calculate the current percentage of the moon phase with the attached file.

The program you attached won't be accurate even on a PC, because it uses floats instead of doubles for calculations.

jremington:
The program you attached won't be accurate even on a PC, because it uses floats instead of doubles for calculations.

The last time I compiled anything on a PC, the compiler used double precision for floats anyway, because the hardware FPU does all computations in double precision. It was a long time ago, I'm not sure if that has changed.

I use Code::Blocks on a PC and C/C++ floats are 32 bits, same as an Arduino.