Raised This Month: $81 Target: $400
 20% 

A calculation problem with floats numbers


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Alon2k2
Junior Member
Join Date: Apr 2010
Old 11-16-2023 , 06:43   A calculation problem with floats numbers
Reply With Quote #1

Hi,

I have a problem with doing calculations like 0.01 + 0.03.
Is there toFixed for this thing like in JavaScript?

Code:
new Float:floatVal = 0.01 + 0.03;
PrintToChat(client, "$%.2f", floatVal); // $0.03 wrong!!
Alon2k2 is offline
helloworlds
Junior Member
Join Date: Oct 2022
Old 11-23-2023 , 09:38   Re: A calculation problem with floats numbers
Reply With Quote #2

There's probably some more elegant way to do this with arithmetic and/or bit fiddling, but here's one approach that takes advantage of the "FloatToString" function handling this case automagically. It should at least solve your example case.

PHP Code:
#include <sourcemod>

// Parameters:
// f - Floating point number to convert.
// n - At how many decimal points to truncate at.
// out - Buffer to store string in.
// maxlen - Maximum length of string buffer.
// Return value: Number of characters written to the buffer, not including the null terminator.
int FloatToStringTruncate(float fint nchar[] outint maxlen)
{
    
int res FloatToString(FloatFraction(f), outmaxlen);
    
int cutoff n;
    if (
cutoff >= maxlen)
    {
        return 
res;
    }
    
out[cutoff] = '\0';
    return 
Format(outcutoff"%d%s%s",
        
RoundToFloor(f),
        
<= "" ".",
        
out[<= 2]
    );
}

public 
void OnPluginStart()
{
    
float f 0.04;
    
PrintToServer("Plain: %f"f);

    
PrintToServer("Format-class functions: %.2f"f);

    
char buffer[32];
    
FloatToStringTruncate(f2buffersizeof(buffer));

    
PrintToServer("FloatToStringTruncate: %s"buffer);

...or whatever "truncate at n chars after the decimal point" method you'd wanna use.

This outputs:

Quote:
Plain: 0.039999
Format-class functions: 0.03
FloatToStringTruncate: 0.04

Last edited by helloworlds; 11-23-2023 at 09:44.
helloworlds is offline
101
Member
Join Date: Nov 2023
Old 11-24-2023 , 15:44   Re: A calculation problem with floats numbers
Reply With Quote #3

Quote:
Originally Posted by helloworlds View Post
There's probably some more elegant way to do this with arithmetic and/or bit fiddling, but here's one approach that takes advantage of the "FloatToString" function handling this case automagically. It should at least solve your example case.

PHP Code:
#include <sourcemod>

// Parameters:
// f - Floating point number to convert.
// n - At how many decimal points to truncate at.
// out - Buffer to store string in.
// maxlen - Maximum length of string buffer.
// Return value: Number of characters written to the buffer, not including the null terminator.
int FloatToStringTruncate(float fint nchar[] outint maxlen)
{
    
int res FloatToString(FloatFraction(f), outmaxlen);
    
int cutoff n;
    if (
cutoff >= maxlen)
    {
        return 
res;
    }
    
out[cutoff] = '\0';
    return 
Format(outcutoff"%d%s%s",
        
RoundToFloor(f),
        
<= "" ".",
        
out[<= 2]
    );
}

public 
void OnPluginStart()
{
    
float f 0.04;
    
PrintToServer("Plain: %f"f);

    
PrintToServer("Format-class functions: %.2f"f);

    
char buffer[32];
    
FloatToStringTruncate(f2buffersizeof(buffer));

    
PrintToServer("FloatToStringTruncate: %s"buffer);

...or whatever "truncate at n chars after the decimal point" method you'd wanna use.

This outputs:
I Don't Know Why This Happens , But What about this :

PHP Code:
#include <sourcemod>
#define fix    0.0000001 // Fix ONLY FOR PRINT Floats (Don't Use During Calculations)

public OnPluginStart() 
{
    
RegServerCmd("sm_test",Command_test,"Test Floats");
}

public 
Action:Command_test(args)
{
    
float X=0.03;
    
float Z=0.01;
    
PrintToServer("fixed X+Z = %f",X+Z+fix); // Result 0.040000
    
PrintToServer("Abs X+Z = %f",X+Z); // Result 0.039999

101 is offline
helloworlds
Junior Member
Join Date: Oct 2022
Old 11-26-2023 , 08:10   Re: A calculation problem with floats numbers
Reply With Quote #4

Quote:
Originally Posted by 101 View Post
I Don't Know Why This Happens [...]
It has to do with the fact that float32 are represented as a sign bit, 8 bits for exponent, and 23 bits for the fraction, and you just can't represent all values accurately with this. For more info, see:
https://en.wikipedia.org/wiki/IEEE_754, https://en.wikipedia.org/wiki/Single...g-point_format
helloworlds is offline
101
Member
Join Date: Nov 2023
Old 11-26-2023 , 09:16   Re: A calculation problem with floats numbers
Reply With Quote #5

So the bits of fraction insist on carrying Nonzero numbers no matter what the result!

by the way, thank you I found extra information here :
https://stackoverflow.com/questions/...floating-point

But who can believe that 0.039999 is closer to 0.04 than (0.040000 itself)!
101 is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 12-25-2023 , 13:57   Re: A calculation problem with floats numbers
Reply With Quote #6

Quote:
Originally Posted by Bacardi View Post
You can try trick output message, by adding:
+ 0.0000001

PHP Code:
    float value 1.0;
    
    
PrintToServer("= value %.2f"value);


    
value += 0.01;
    
    
PrintToServer("- value %f"value);
    
PrintToServer("- - value %f"value 0.0000001);
    
PrintToServer("- - value %.2f"value);
    
PrintToServer("- - value %.2f"value 0.0000001); 
Code:
= value 1.00
- value 1.009999
- - value 1.010000
- - value 1.00
- - value 1.01
__________________
Do not Private Message @me
Bacardi is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 22:15.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode