Let's say I have x = 12.345
. In javascript, what function floatToInt(x)
has the fastest running time such that floatToInt(12.345)
returns 12
?
Great Question! I actually had to deal with this the other day! It may seem like a goto to just write parseInt but wait! we can be fancier.
So we can use bit operators for quite a few things and this seems like a great situation! Let's say I have the number from your question, 12.345, I can use the bit operator '~' which inverts all the bits in your number and in the process converts the number to an int! Gotta love JS.
So now we have the inverted bit representation of our number then if we '~' it again we get ........drum roll......... our number without the decimals! Unfortunately, it doesn't do rounding.
var a = 12.345;
var b = ~~a; //boom!
We can use Math.round() for that. But there you go! You can try it on JSperf to see the slight speed up you get! Hope that helps!
Math.random()
always takes the exact same amount of time and that converting any possible result to an integer is always a constant time too. You should not have Math.random()
in your test at all and you should be comparing a conversion of the same number for each method. Your method probably is faster, but this is a poorly designed test. When I run your test in Chrome, I see no meaingful difference between the first three methods. –
Tortuous Math.random
is pretty much necessary for these kind of tests. It ensures that the operation is not constant-folded by an optimising compiler. Oh, microbenchmarks are hard… –
Jessie Math.random()
has to be outside the timed region so you can time only the operation that actually matters. –
Tortuous Math.round
call or ~~
operation with the tools that JS gives you. And if you're timing a loop (like jsperf does), Math.random()
has to go in the body. But we can reasonably assume that every Math.random()
call takes the same time (on average, at least), so that we can still compare the differences of the other operations. –
Jessie testNumbers
, it would only consist of integers after the first run. You'd need to move the slice
inside the timed region. But the idea is good, if you don't trust Math.random
, you should be able to do something like that –
Jessie resultArray
so the testNumbers
array is never disturbed so no .slice()
is needed and it always runs on the random numbers: jsperf.com/float-to-int-conversion-comparison/30. –
Tortuous x = 10000000000
: Math.floor(x) === x
, but ~~x === 1410065408
. Math.floor(-0.5) === -1
, but ~~(-0.5) === 0
–
Pancreas b = ~~(a + 0.5)
for rounding –
Indicate x = 10000000000
? –
Polis ~~2147483648.88
gives -2147483648
. –
Trilateration this is a good example i think
var intvalue = Math.floor( floatvalue );
var intvalue = Math.ceil( floatvalue );
var intvalue = Math.round( floatvalue );
Arithmetic OR with zero does the trick.
> 12 === (0 | 12.245)
true
parseInt(x)
does the work.
If you were running checks to see if the returned value is actually an int without the knowledge of what is the input.
x = 12.245; // Issa number
x = 'School'; // Not a number
y = parseInt(x)
if isNaN(y)
console.log('Not a number');
else
console.log('Issa number');
// Issa number
while using y = ~~x
is a totally different case
x = 12.245; // Issa number
x = 'School'; // Issa number
y = ~~x;
if isNaN(y)
console.log('Not a number');
else
console.log('Issa number');
In my own testing, I've found that the rule of thumb for performance is:
- Bitwise operations (
~~num, num|0, num^0, num&0xFFFFFFFF
) - Math methods
num - (num % 1)
- parseInt
The issue with bitwise operators is that the numbers will be cast to 32bit integers in the process, if that is fine for your use-case then go ahead. See MDN docs on bitwise OR, bitwise NOT, bitwise AND and bitwise XOR or their respective ECMAScript documentation.
The parseInt
function is usually way slower than the alternatives, most likely because it expects a string as parameter.
The solution with the modulo operator should be used with caution as it may bite you in the ass sometime due to floating point issues but is almost as fast as the Math methods.
If you don't care about the rounding specifics, Math.trunc()
is easy, standard, and readable. I haven't tested performance, but it must be better than Math.round()
and parseInt()
.
© 2022 - 2024 — McMap. All rights reserved.
Math.round
(orMath.floor
, depending what you need). – Jessie~~
has important edge cases you would need to consider. And it might not be faster at all. – Jessie