### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Odd way of calculating the Logarithm  (Read 1097 times)

#### jamie

• Hero Member
• Posts: 4445
##### Re: Odd way of calculating the Logarithm
« Reply #15 on: April 21, 2021, 01:40:34 am »
Ok, so why aint any one using them ?

I didn't know that, I normally hang out in Delphi land..

Thanks for telling that, Maybe that can be used instead.
The only true wisdom is knowing you know nothing

#### engkin

• Hero Member
• Posts: 2692
##### Re: Odd way of calculating the Logarithm
« Reply #16 on: April 21, 2021, 01:59:46 am »
Ok, so why aint any one using them ?

I do use them, like here.

#### PascalDragon

• Hero Member
• Posts: 2969
• Compiler Developer
##### Re: Odd way of calculating the Logarithm
« Reply #17 on: April 21, 2021, 09:11:28 am »
May I ask you what "dedicated function" means. As I understand from your answer it must be some "better version" of calculating log2 in a unique way for each number. Am I wright? Why isn't this implemented in 64bit?

No, there is not, because Double which is the highest available floating point type available on Win64 as well as any non-x86 system simply cannot represent 3 exactly (as well as many other values). So no matter what you do, Trunc of that will simply return 2 (in case its Double representation is less than 3) and that is correct.

#### MathMan

• Full Member
• Posts: 217
##### Re: Odd way of calculating the Logarithm
« Reply #18 on: April 21, 2021, 11:00:06 am »
May I ask you what "dedicated function" means. As I understand from your answer it must be some "better version" of calculating log2 in a unique way for each number. Am I wright? Why isn't this implemented in 64bit?

No, there is not, because Double which is the highest available floating point type available on Win64 as well as any non-x86 system simply cannot represent 3 exactly (as well as many other values). So no matter what you do, Trunc of that will simply return 2 (in case its Double representation is less than 3) and that is correct.

I beg to differ here. The value 3 can be represented exact as a finite binary floating point value (in fp32 single, fp64 double or fp80 extended). What can not be represented exact as a finite binary floating point value is e.g. 0.1 (aka one tenth).

MathMan

#### dseligo

• Full Member
• Posts: 231
##### Re: Odd way of calculating the Logarithm
« Reply #19 on: April 21, 2021, 11:10:10 am »
recently I discovered that Lazarus/FreePascal calculates
Code: Pascal  [Select][+][-]
1. Trunc(Log2(8))
as 2.

You could do it like this:
Code: Pascal  [Select][+][-]
1. Trunc(Currency(Log2(8)))

#### PascalDragon

• Hero Member
• Posts: 2969
• Compiler Developer
##### Re: Odd way of calculating the Logarithm
« Reply #20 on: April 21, 2021, 01:52:16 pm »
May I ask you what "dedicated function" means. As I understand from your answer it must be some "better version" of calculating log2 in a unique way for each number. Am I wright? Why isn't this implemented in 64bit?

No, there is not, because Double which is the highest available floating point type available on Win64 as well as any non-x86 system simply cannot represent 3 exactly (as well as many other values). So no matter what you do, Trunc of that will simply return 2 (in case its Double representation is less than 3) and that is correct.

I beg to differ here. The value 3 can be represented exact as a finite binary floating point value (in fp32 single, fp64 double or fp80 extended). What can not be represented exact as a finite binary floating point value is e.g. 0.1 (aka one tenth).

I stand corrected.

I've looked at the problem again and what might work is to tweak the 1/ln(2) constant that is used inside log2 for each of the supported maximum floating point type. E.g. the current one is 1.4426950408889634079 which is correct for Extended, but for Double the value t1.4426950408889635 results in more correct values (at least they're overestimating instead of underestimating). Similar for Single and probably also for log10.

#### Salazar

• New member
• Posts: 9
##### Re: Odd way of calculating the Logarithm
« Reply #21 on: April 21, 2021, 02:33:13 pm »
@dseligo
This works with a minimal interference in the existig code. Thank you!

@PascalDragon
I understand, that - in general - decimal numbers can not be represented exactly in the binary system. But why is the calculation in question different in Win32 and Win64?
Is it so, that for some numbers the calculation gives the expected result and for others not - dependent from the conversation from binary to decimal? If this is the case then for some numbers the outcome of trunc(log2(number)) might be as expected in Win32 - for others in Win64.

Please confer what Bart wrote earlier in this post. From his post I got the impression, that the calculation allways leads to expected results in Win32.

I hope that the thread does not get to sophisticated here, but I am interested in understanding what's really going on.

#### MathMan

• Full Member
• Posts: 217
##### Re: Odd way of calculating the Logarithm
« Reply #22 on: April 21, 2021, 04:54:53 pm »
I've looked at the problem again and what might work is to tweak the 1/ln(2) constant that is used inside log2 for each of the supported maximum floating point type. E.g. the current one is 1.4426950408889634079 which is correct for Extended, but for Double the value t1.4426950408889635 results in more correct values (at least they're overestimating instead of underestimating). Similar for Single and probably also for log10.

I suspected that much, when I saw the code excerpt provided by Bart. Is it possible to define floats in hex format (within the scope of system libraries at least)? This could eliminate rounding errors introduced by StrToFloat conversions. Because in theory the specific constant here would need to have decimal representations of 24, 54 or 65 decimal digits - and depending on the lib for conversion to float these may get rounded different.

MathMan
« Last Edit: April 21, 2021, 05:01:32 pm by MathMan »

#### Paolo

• Full Member
• Posts: 169
##### Re: Odd way of calculating the Logarithm
« Reply #23 on: April 21, 2021, 06:22:32 pm »
Quote
in the binary system. But why is the calculation in question different in Win32 and Win64?

Not fully sure, no checked, but I suspect that the different results are due to different precision applied during computation. Win32 shold use extended, win64 double and when come back on the final variable it is rounded accordingly to the var size. The same situation for delphi code.

#### PascalDragon

• Hero Member
• Posts: 2969
• Compiler Developer
##### Re: Odd way of calculating the Logarithm
« Reply #24 on: April 22, 2021, 09:26:45 am »
I understand, that - in general - decimal numbers can not be represented exactly in the binary system. But why is the calculation in question different in Win32 and Win64?
Is it so, that for some numbers the calculation gives the expected result and for others not - dependent from the conversation from binary to decimal? If this is the case then for some numbers the outcome of trunc(log2(number)) might be as expected in Win32 - for others in Win64.

Because Win32 has access to the Extended type, Win64 does not. You would have the same result on any platform that does not support Extended which is any non-x86 (i8086, i386, x86_64) platform and the Win64 one.

I've looked at the problem again and what might work is to tweak the 1/ln(2) constant that is used inside log2 for each of the supported maximum floating point type. E.g. the current one is 1.4426950408889634079 which is correct for Extended, but for Double the value t1.4426950408889635 results in more correct values (at least they're overestimating instead of underestimating). Similar for Single and probably also for log10.

I suspected that much, when I saw the code excerpt provided by Bart. Is it possible to define floats in hex format (within the scope of system libraries at least)? This could eliminate rounding errors introduced by StrToFloat conversions. Because in theory the specific constant here would need to have decimal representations of 24, 54 or 65 decimal digits - and depending on the lib for conversion to float these may get rounded different.

The system libraries are not in any way "magic" regarding this. A hexadecimal value will be interpreted as an ordinal and then converted to the floating point type. What might work is a record.