#(Int to Float) Turn X into 0.X
1 messages · Page 1 of 1 (latest)
parseFloat - this is JS function but your post is tagged C#
float.Parse
gotcha
just generally pointed out the idea
Something like x / pow(10, floor(log10(abs(n)))+1) for any non-zero n
do you think this solution would prove better than the string one?
it sure isn't cleaner
much
but yeah I've once looked into an integer parsing method and it is long and loopy
floor(log10(abs(n)))+1 - this formula calculates how many digits a number has. so for 123, it'll return 3. for 9 it'll return 1. for 1000 it'll return 4
I assume floats are even worse
but this formula breaks for n = 0, and maybe n < 0 too
no wait abs duh
it works for n < 0, just not n = 0
but you could just add in a case for that and if n = 0, the digit count is obviously just 1
oh you might need to +2 actually
because you need one more digit than the number of digits in the original number
essentially you want to get the value 1000 from a 3 digit number like 274. because then you do 274 / 1000, which gives you 0.274
no wait. 1 followed by as many zeroes as there are digits
so +1 is fine
But yes I strongly believe so. If you like we can do a quick benchmark
Yeah the parsing methods look ugly and logically speaking are prob more time consuming
so you mean x and n are identical here
ooh I wanna see how much better that is
I've built many many lexers and parsers in the past and I am just experimenting with different ways to make them, which are hopefully easier / more maintainable / more performant and kinda wanna see where I find my best balance between the three
THAT I wanna benchmark later lol
Okay, these are my two methods
[Benchmark]
[Arguments(274)]
public float UsingToStringAndParse(int value)
{
return float.Parse($"0.{value}");
}
[Benchmark]
[Arguments(274)]
public float UsingDivide(int value)
{
if (value == 0)
{
return 0;
}
return value / MathF.Pow(10, MathF.Floor(MathF.Log10(MathF.Abs(value))) + 1);
}
I already know the string version is going to cost an allocation
but I'm actually more interested in speed here
Okay yeah, as expected. Much faster. And also no allocations
| Method | value | Mean | Error | StdDev | Allocated |
|---------------------- |------ |---------:|---------:|---------:|----------:|
| UsingToStringAndParse | 274 | 93.47 ns | 1.084 ns | 0.961 ns | 32 B |
| UsingDivide | 274 | 20.39 ns | 0.092 ns | 0.077 ns | - |
Hope that helps @orchid folio
I was doubtful because of the Pow call, because Pow is not that performant. But looks like my worry was misplaced, runs just fine
Oh wow
yeah that's quite the difference
nearly 5 times over
wait
oop I feel dumb seeing multiple numbers and not knowing which one directly corrolates to time
Mean
that's the one for time
Error is just error margin, StdDev is standard deviation, not terribly important
Oh wait I didn't see the headers
Mean and Allocated are the two important columns
Pure-math solution is both faster, and more memory efficient
I figured it'd be, thank you :D
You're welcome!
On another note
assuming I have a string which I 100% is a valid int..
is there a better way to parse it? such as iterating over characters and do val *= 10; val += char.GetCharacterDigit(c); (not sure if that's exactly the method's name)
char.GetNumericValue, but no, that is much much worse
really? I figured because int.Parse checks the validity of the string it'd be worse
well yeah, you want that to happen
2⅜9 isn't a valid integer, but using your supposed solution it would parse "fine"
I see