It is currently October 9th, 2024, 3:45 pm

[NOT A BUG] Floating Point Imprecision

Report bugs with the Rainmeter application and suggest features.
User avatar
Yincognito
Rainmeter Sage
Posts: 8395
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

[NOT A BUG] Floating Point Imprecision

Post by Yincognito »

Skin:

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1
BackgroundMode=2
SolidColor=47,47,47,255

---Measures---

[Value]
Measure=Calc
Formula=Log(1-Frac(4294967295.999))

---Meters---

[Result]
Meter=String
FontColor=255,255,255,255
FontFace=Consolas
FontSize=16
Padding=5,5,5,5
AntiAlias=1
MeasureName=Value
NumOfDecimals=5
Text=Value = %1
UpdateDivider=-1
DynamicVariables=1
Issue:
- the result should be -3.00000 and not -3.00003 (see the Rainmeter log too)

Notes:
- both Frac(4294967295.999) and 1-Frac(4294967295.999) yield the correct results, i.e. 0.999 and 0.001
- because of that, Log() of the above should yield the integral -3 or -3.00000, just like the plain Log(0.001) does
- if I remove 2 digits to make Formula=Log(1-Frac(42949672.999)), the result is correct, but becomes less precise the larger the number
- this is not limited to the Log() function, it occurs when similar many digits values (e.g. around 14 or 15, like 1234567890.12345) are used in computations
- it looks like a floating point range issue (somewhat normal), I just wonder if it can be avoided, and if so, what's the range that guarantees correct results

P.S. I think I touched some related subjects in the past, just can't remember which of them included floating point imprecision out of a certain range.

EDIT: Curiously, the issue also happens if I break the 1 Calc measure into 2 Calc measures (despite the value of the 1st being reasonable), e.g.:

Code: Select all

[Number]
Measure=Calc
Formula=(1-Frac(4294967295.999))

[Value]
Measure=Calc
Formula=Log(Number)
and of course, doesn't happen if I use the string value of the 1st Calc measure:

Code: Select all

[Number]
Measure=Calc
Formula=(1-Frac(4294967295.999))

[Value]
Measure=Calc
Formula=Log([Number])
DynamicVariables=1
Also, it happens when using variables instead of measures.

I think it would be nice if we'd be able to get the correct result in a single Calc measure instead of using all kinds of tricks to force it to be correct. :confused:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Active Colors
Moderator
Posts: 1318
Joined: February 16th, 2012, 3:32 am
Location: Berlin, Germany

Re: [BUG?] Floating Point Imprecision

Post by Active Colors »

Yincognito wrote: August 1st, 2024, 11:12 am P.S. I think I touched some related subjects in the past, just can't remember which of them included floating point imprecision out of a certain range.
I remember it was probably in these threads

https://forum.rainmeter.net/viewtopic.php?t=42416
https://forum.rainmeter.net/viewtopic.php?t=40251
https://forum.rainmeter.net/viewtopic.php?t=36112
https://forum.rainmeter.net/viewtopic.php?t=31054
https://forum.rainmeter.net/viewtopic.php?t=24399#p129442

From this thread:
https://forum.rainmeter.net/viewtopic.php?t=35984#p182711
“The reason is because of how numbers are stored in Rainmeter. Every measure's number value is stored as a floating point number and when converted to a string, it can sometimes include extra decimal points. So a number like "12", can be represented internally like "12.0000000001". These conversions can cause the regular expression to fail.”
User avatar
Yincognito
Rainmeter Sage
Posts: 8395
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Floating Point Imprecision

Post by Yincognito »

Active Colors wrote: August 1st, 2024, 2:25 pm I remember it was probably in these threads

https://forum.rainmeter.net/viewtopic.php?t=42416
https://forum.rainmeter.net/viewtopic.php?t=40251
https://forum.rainmeter.net/viewtopic.php?t=36112
https://forum.rainmeter.net/viewtopic.php?t=31054
https://forum.rainmeter.net/viewtopic.php?t=24399#p129442

From this thread:
https://forum.rainmeter.net/viewtopic.php?t=35984#p182711
“The reason is because of how numbers are stored in Rainmeter. Every measure's number value is stored as a floating point number and when converted to a string, it can sometimes include extra decimal points. So a number like "12", can be represented internally like "12.0000000001". These conversions can cause the regular expression to fail.”
Thanks for looking for those threads, now it really seems like I'm rambling the same thing in different ways over and over again... :oops:

The explanation is spot on, and I've faced similar issues in my Earth "skin" written in Javascript, having to go back and forth between numbers and strings to conserve precision (which I eventually did, in spite of everything, and for similar numbers). Anyway, it's crazy that I can't even get (Ceil(Abs(Log(Abs(1-Frac(65534.999)))))) to yield 3 and not 4, even though I really lowered the bar from 4294967295.999.

Obviously, it's not necessarily Rainmeter's fault, but this means that we'd have to stick with rudimentar operations (addition, subtraction, nothing fancy) on very small numbers, or risk having a wrong result going forward. :???:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
MikeG621
Posts: 89
Joined: March 18th, 2013, 1:59 pm

Re: [BUG?] Floating Point Imprecision

Post by MikeG621 »

This looks like general floating point shenanigans, and can even mess with comparisons so depending on what I'm doing I tend to round values before doing anything with them to deal with that extra .0000001 or whatever that may be in there.
User avatar
Yincognito
Rainmeter Sage
Posts: 8395
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Floating Point Imprecision

Post by Yincognito »

MikeG621 wrote: August 5th, 2024, 1:27 pm This looks like general floating point shenanigans, and can even mess with comparisons so depending on what I'm doing I tend to round values before doing anything with them to deal with that extra .0000001 or whatever that may be in there.
Good idea, though in this case the rounding must be done in the proper stage (i.e. Formula=(Ceil(Abs(Log(Abs(Round(1-Frac(4294967295.999),5))))))), to not defeat the formula's purpose (i.e. to compute the number of integral and decimal digits from a number with as much precision as possible using only numerical functions).

Thanks for the idea, sometimes the easiest solutions are the easiest to miss. In the end, I used - what else - the never failing strings / regexes to do the above in my actual code, and ditched the numerical way entirely, but I'll keep your idea in mind the next time I'll need it (hopefully I'll also remember to not post yet another topic regarding these things here). :thumbup:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
MikeG621
Posts: 89
Joined: March 18th, 2013, 1:59 pm

Re: [NOT A BUG] Floating Point Imprecision

Post by MikeG621 »

Yincognito wrote: August 5th, 2024, 6:12 pmGood idea, though in this case the rounding must be done in the proper stage
Of course, the use case isn't universal. What I'm usually doing is applying the rounding to the log so I can compare arbitrary non-integer values: Round(Log10(value), 5), with Floor or Ceiling if necessary.
User avatar
Yincognito
Rainmeter Sage
Posts: 8395
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [NOT A BUG] Floating Point Imprecision

Post by Yincognito »

MikeG621 wrote: August 12th, 2024, 2:29 pm Of course, the use case isn't universal. What I'm usually doing is applying the rounding to the log so I can compare arbitrary non-integer values: Round(Log10(value), 5), with Floor or Ceiling if necessary.
Indeed. How it's done depends from case to case, but the idea is good nevertheless. Thanks again! :great:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth