C
C#16mo ago
WaffleDevs

❔ Need Help Understanding Casting

I have an equation that returns a float of value 0.6561f. When i cast it to a double, it turns into 0.6560999751091003d. I don't understand why. Equation: Mathf.Pow(Math.Max((float)num - 300f, 0f) / 1200f, 2f Double: (double)Mathf.Pow(Math.Max((float)num - 300f, 0f) / 1200f, 2f int num = 1272 Mathf.Pow(float f, float p) returns (float)Math.Pow((double)f, (double)p);
56 Replies
cap5lut
cap5lut16mo ago
thats simply the closest u can get with how floating point numbers work
Angius
Angius16mo ago
If something that involves floats produces numbers you did not expect in the nth decimal place it's always because of floating point rounding errors
cap5lut
cap5lut16mo ago
double isnt exactly float + more if u want to know more about the internal "structure" of the floating point types, u can read about it here: https://learn.microsoft.com/en-us/cpp/c-language/type-float?view=msvc-170
Kouhai
Kouhai16mo ago
You can't represent 0.6561f in a 32bit float, 32 bits are just not precise enough https://float.exposed/0x3f27f62b
WaffleDevs
WaffleDevsOP16mo ago
So .65609..........d is the closest a double can be to .6561? And if yes, is there any way I can replicate coversion that in js?
Kouhai
Kouhai16mo ago
No a double can accurately represent 0.6561 as 0.65610000000000001652
WaffleDevs
WaffleDevsOP16mo ago
Then why isnt it?
Kouhai
Kouhai16mo ago
Because 32bit representation of 0.6561f is not accurate enough it's actually 0.6560999751091
WaffleDevs
WaffleDevsOP16mo ago
Oh
MODiX
MODiX16mo ago
Kouhai /人◕ ‿‿ ◕人\
REPL Result: Success
var val = 0.6560999751091f;
Console.WriteLine(val);
var val = 0.6560999751091f;
Console.WriteLine(val);
Console Output
0.6561
0.6561
Compile: 552.432ms | Execution: 68.937ms | React with ❌ to remove this embed.
WaffleDevs
WaffleDevsOP16mo ago
yea.. I just need a way to convert .6561 in js to 0.6560999751091 then, and ill be golden
Kouhai
Kouhai16mo ago
Do you want the less accurate representation 0.6560999751091 or the more accurate one 0.6561?
WaffleDevs
WaffleDevsOP16mo ago
I need 0.6560999751091
Kouhai
Kouhai16mo ago
Do you want the same equation Mathf.Pow(Math.Max((float)num - 300f, 0f) to return 0.6560999751091 in JS?
WaffleDevs
WaffleDevsOP16mo ago
I would just prefer a function to change to it myself
Kouhai
Kouhai16mo ago
Well, numbers in JS are 64 bit So you can't really get this 0.6560999751091 by just executing the equation in JS
WaffleDevs
WaffleDevsOP16mo ago
I get that
Kouhai
Kouhai16mo ago
Why do you want a 32bit representation though?
WaffleDevs
WaffleDevsOP16mo ago
I am making a website to generate a map of the world of a game. The site is made in JS and the game is made via Unity. I am recreating the function for generating into js. I would like the site to be 100% accurate, but if it is impossible, that is ok.
Kouhai
Kouhai16mo ago
Ah I see, so the map generation is originally done in C#, but you want a web version of it
WaffleDevs
WaffleDevsOP16mo ago
yep
Kouhai
Kouhai16mo ago
Well I guess you can do something like this Math.fround(Math.pow(Math.max(num - 300, 0) / 1200, 2))
WaffleDevs
WaffleDevsOP16mo ago
I got this via js
WaffleDevs
WaffleDevsOP16mo ago
Kouhai
Kouhai16mo ago
Right, instead of allocating an array you could do Math.fround which convert to 32bit then 64bit, so you get a less accurate representation!
WaffleDevs
WaffleDevsOP16mo ago
It works, but there is 3 extra digits at the end... (for both the Float32Array and Math.fround)
Kouhai
Kouhai16mo ago
Yeah, that's normal It's how it's actually represented in C# as well
WaffleDevs
WaffleDevsOP16mo ago
So console writeline-ing it just chops those off? I answered my own question. Yes!
Console.WriteLine((double)Math.Clamp(Mathf.Pow(Math.Max((float)num - 300f, 0f) / 1200f, 2f), 0f, 1f) == 0.6560999751091d); // returns false
Console.WriteLine((double)Math.Clamp(Mathf.Pow(Math.Max((float)num - 300f, 0f) / 1200f, 2f), 0f, 1f) == 0.6560999751091d); // returns false
Console.WriteLine((double)Math.Clamp(Mathf.Pow(Math.Max((float)num - 300f, 0f) / 1200f, 2f), 0f, 1f) == 0.6560999751091003d); // returns true
Console.WriteLine((double)Math.Clamp(Mathf.Pow(Math.Max((float)num - 300f, 0f) / 1200f, 2f), 0f, 1f) == 0.6560999751091003d); // returns true
I appreciate the help Kouhai! I also appreciate how fast this server responds to questions 🙂
Kouhai
Kouhai16mo ago
Np, this server is indeed amazing! <:MadoThumbsUp_MM:406514447973351444>
WaffleDevs
WaffleDevsOP16mo ago
Works like a charm after implemented!
WaffleDevs
WaffleDevsOP16mo ago
Actually I am taking that back... 2/5 are inaccurate
WaffleDevs
WaffleDevsOP16mo ago
I am working on seeing if it is an issue with something else. I found a problem. No clue if it is "the" problem. Yes it is a problem. This time i need Int32's in js :L JS: 900 * 931937597 = 838743837300 C#: 900 * 931937597 = 1225214580 I understand if further I need to move to a javascript help server, though I would like to see how far I can get with this problem here.
Angius
Angius16mo ago
Well, JS has no integers, so...
WaffleDevs
WaffleDevsOP16mo ago
Well yea but atleast there is 1 solution...
WaffleDevs
WaffleDevsOP16mo ago
I am just going to have a permanent array for this. Performance will hopefully not be too bogged down due to this.
Kouhai
Kouhai16mo ago
Use Math.imul to get a 32bit int Math.imul(900 , 931937597)
WaffleDevs
WaffleDevsOP16mo ago
gg New issue. I need double to float.
Angius
Angius16mo ago
You're going to lose precision
WaffleDevs
WaffleDevsOP16mo ago
I need too C#: Math.Clamp(num3 * (double)((float)that), 0.0, 1.0); that is of type double That: 0.3809662695885479 Float cast of That: 0.38096628 Double cast of Float cast of That: 0.38096627593040466
Angius
Angius16mo ago
This is the point where I feel obliged to ask "why" Why the constant juggling back and forth between floats and doubles?
WaffleDevs
WaffleDevsOP16mo ago
Source code of the map generation function of the game im making a tool for Ask the dev, not me ¯\_(ツ)_/¯ I know Kouhai is going to come out of the shadows and give me a different answer, but i am going to be sticking with new Float32Array([that])[0]) for the JS version
Kouhai
Kouhai16mo ago
Why would do that Monka Though still you could do Math.fround(....)
WaffleDevs
WaffleDevsOP16mo ago
C#: Math.Clamp(num3 * (double)((float)random2.NextDouble()), 0.0, 1.0); JS: CSharpMath.Clamp(num3 * new Float32Array([random2.NextDouble()])[0], 0, 1); This is what i got, and they are equals But i am experiencing something odd. still testing myself before asking though
Kouhai
Kouhai16mo ago
Why allocate an array when you can use Math.fround?
WaffleDevs
WaffleDevsOP16mo ago
doesnt do what i need That turns it to a double i need it to be a float
Kouhai
Kouhai16mo ago
Math.fround does the exact same thing From MDN
The Math.fround() static method returns the nearest 32-bit single precision float representation of a number.
Angius
Angius16mo ago
There are only doubles in JS You can strip some decimal spaces Or round things up In the end, you will get a double
Kouhai
Kouhai16mo ago
^
WaffleDevs
WaffleDevsOP16mo ago
For some reason it wasnt working last time i was doing it. I dont know what but it does now wrong replied message (float)that = Math.fround(that) = 0.448212206363678 for both languages. C#: (double)(Mathf.SmoothStep(0.008f, 0.05f, ((float)num - 2400f) / 1000f) * (float)that); 0.003585697850212455 JS: (CSharpMath.SmoothStep(0.008, 0.05, (num - 2400) / 1000) * Math.fround(that)); 0.003585697650909424 JS: Math.fround(CSharpMath.SmoothStep(0.008, 0.05, (num - 2400) / 1000) * Math.fround(that)); 0.003585697617381811 Thats shitty to look ath but gets the point across SmoothStep = 0.008 for both
Angius
Angius16mo ago
Because C# actually uses floats when told, while JS always uses doubles
WaffleDevs
WaffleDevsOP16mo ago
Yes i get that. Ive been told that more than twice during this Every single time there was some work around
Angius
Angius16mo ago
The only workarounds when working with floats entail working around rounding errors For example, you could say the precision of 5 decimal places is enough for you and truncate everything to that
WaffleDevs
WaffleDevsOP16mo ago
I have solved the issue
Angius
Angius16mo ago
For comparison, you'd do floatOne - floatTwo <= 0.0001 instead of floatOne == floatTwo etc
WaffleDevs
WaffleDevsOP16mo ago
Fucked this up 🙂 Needed to fround js's and compare as a double. it was actually 0.00800000037997961d instead of the 0.008f i was stuck on I am very thankful for all the help you guys (mainly Kouhai) provided 🙂
Accord
Accord16mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server