❔ 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
thats simply the closest u can get with how floating point numbers work
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
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
You can't represent
0.6561f
in a 32bit float, 32 bits are just not precise enough
https://float.exposed/0x3f27f62bSo
.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?No a double can accurately represent
0.6561
as 0.65610000000000001652
Then why isnt it?
Because 32bit representation of 0.6561f is not accurate enough it's actually
0.6560999751091
Oh
Kouhai /人◕ ‿‿ ◕人\
REPL Result: Success
Console Output
Compile: 552.432ms | Execution: 68.937ms | React with ❌ to remove this embed.
yea..
I just need a way to convert
.6561
in js to 0.6560999751091
then, and ill be goldenDo you want the less accurate representation
0.6560999751091
or the more accurate one 0.6561
?I need
0.6560999751091
Do you want the same equation
Mathf.Pow(Math.Max((float)num - 300f, 0f)
to return 0.6560999751091
in JS?I would just prefer a function to change to it myself
Well, numbers in JS are 64 bit
So you can't really get this
0.6560999751091
by just executing the equation in JSI get that
Why do you want a 32bit representation though?
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.
Ah I see, so the map generation is originally done in C#, but you want a web version of it
yep
Well
I guess you can do something like this
Math.fround(Math.pow(Math.max(num - 300, 0) / 1200, 2))
I got this via js
Right, instead of allocating an array you could do
Math.fround
which convert to 32bit then 64bit, so you get a less accurate representation!It works, but there is 3 extra digits at the end...
(for both the Float32Array and Math.fround)
Yeah, that's normal
It's how it's actually represented in C# as well
So console writeline-ing it just chops those off?
I answered my own question. Yes!
I appreciate the help Kouhai! I also appreciate how fast this server responds to questions 🙂
Np, this server is indeed amazing! <:MadoThumbsUp_MM:406514447973351444>
Works like a charm after implemented!
Actually I am taking that back... 2/5 are inaccurate
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.Well, JS has no integers, so...
Well yea but atleast there is 1 solution...
I am just going to have a permanent array for this. Performance will hopefully not be too bogged down due to this.
Use
Math.imul
to get a 32bit int
Math.imul(900 , 931937597)
gg
New issue. I need double to float.
You're going to lose precision
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
This is the point where I feel obliged to ask "why"
Why the constant juggling back and forth between floats and doubles?
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 versionWhy would do that
Though still you could do
Math.fround(....)
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 thoughWhy allocate an array when you can use
Math.fround
?doesnt do what i need
That turns it to a double
i need it to be a float
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.
There are only doubles in JS
You can strip some decimal spaces
Or round things up
In the end, you will get a double
^
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 bothBecause C# actually uses floats when told, while JS always uses doubles
Yes i get that. Ive been told that more than twice during this
Every single time there was some work around
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
I have solved the issue
For comparison, you'd do
floatOne - floatTwo <= 0.0001
instead of floatOne == floatTwo
etcFucked 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 🙂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.