Calculating large numbers and adding precise values

Just a programming question

I have a value of 28.,000.,000 (yes, 28 million) as unsigned long
Then I do an adding of 800 as integer
This gives 28,000.,800 exaclty as espected.

But now instead of 800 as integer, I want to
add 800.25 so I get a value of 28,000,800.25

Or better explanation:

MarkT:
You are getting towards the limit of what 32 bits can represent, so you might need
to consider splitting the number into a long int part and a float to represent the
fractional part - writing an add/subtract routine isn't too hard, multiply/divide is going to
be "interesting"...

Yes, it is interesting, therefor the famous code

unsigned long tuning_word = (frequency * pow(2, 32)) / DDS_CLOCK;
digitalWrite (LOAD, LOW);

shiftOut(DATA, CLOCK, LSBFIRST, tuning_word);
shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 8 );
shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 16 );
shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 24 );
shiftOut(DATA, CLOCK, LSBFIRST, 0x0);
digitalWrite (LOAD, HIGH);

I do a temperature measurement with a DS18B20.
Normal temperature is 40 degree Celsius. But then
I read 39,94 degree Celsius. And I know I have a
drift of 4Hz/Celsius. So my tone is not 800Hz,
but 799,76Hz. Therefore I want to add 0,24Hz
to the 800Hz. To get the desired frequency
I also add 28.094.200Hz. My programmed
frequency is then 28.095.000,24Hz And then
is the drift corrected. And this all must be
bitshifted.

So my formula is: tuning_word = (28095000,24 * pow(2, 32)) / 125000000;

Ofcourse the 28095000,24 is variable

Didn't saw earlier, only with experimenting proofed (and a bit math)

The tuning_word has a resolution of 0.0291 so let round it to 0.03
For a change of eg. 24hz I need to add 800, hey it's an easy integer

Other advantage I saw, I use only 6 frequencies. But all these will
everytime new calculated (takes processor time). So why not 6
fixed tuning_word's

So problem solved to finetune a DDS

Aon the arduino, you would use fixed point. Always assume the last two places are the tenths and hundredths. So to add 800 you would add 80000. To add 800.25 you would add 80025. You need special routines to print the decimal point correctly.

You are getting towards the limit of what 32 bits can represent, so you might need
to consider splitting the number into a long int part and a float to represent the
fractional part - writing an add/subtract routine isn't too hard, multiply/divide is going to
be "interesting"...

I have a value of 28.,000.,000 (yes, 28 million) as unsigned long
Then I do an adding of 800 as integer
This gives 28,000.,00 exaclty as espected

Well it might be what you expected but it's not what I expected :slight_smile: