0

I have a function which takes a fractional number, and converts it to an integer combined with a binary exponent.

For example, get_whole_number(10.5) will return => 21, 1, where

  • 21 is the integer
  • 1 is the power of 2 you must divide the 21 by to get the original float number (21/(2**1) = 10.5).

So far I have this function, and it works but it is inefficient and slow:

function get_whole_number(number, exponent=0) {
    if(number%1 == 0) return [number, exponent];
    exponent++;
    number *= 2;
    if(exponent >= 500) return [Math.round(number), exponent];
    return get_whole_number(number, exponent);
};

console.log(
  get_whole_number(1.125).join("/2^"));

To make it faster, I wanted to replace some operations, notably number%1 and Math.round with bitwise operations.

So my question is, how do I go about replacing % 1 and round() with bitwise operators?

I was thinking that I could use:

  • if((number & number) == number) instead of if(number%1 == 0) because bitwise operations ignore the fractional part of a number; but this only works sometimes.
  • (number | number) instead of Math.round(number) but this just truncates the value.
Krokodil
  • 1,165
  • 5
  • 19
  • 3
    _"...but it is inefficient and slow"_ - Is it? Who told you that? – Andreas Sep 30 '21 at 12:41
  • @Andreas maybe it isn't exactly slow, but it could be faster, and is wasting some computation time which could be avoided – Krokodil Sep 30 '21 at 12:44
  • 3
    99.99999% of times these optimizations are not necessary or do not have such a significant effect. Not only are you wasting your time focusing on that, you are also making the code less readable, more prone to undefined behavior, not resolving the real performance issues, and more importantly not focusing on features and usability. – Gonnen Daube Sep 30 '21 at 12:45
  • 3
    [What optimizations are premature?](https://softwareengineering.stackexchange.com/questions/79938/what-optimizations-are-premature) – Andreas Sep 30 '21 at 12:46
  • The problem might just be me, but `get_whole_number` just makes no sense to me. What does it do? Why? What does it return? I'm more confused the more i look at it. – Jesper Sep 30 '21 at 12:46
  • @Jesper it creates two integers from one float. So I use it when representing a fraction in terms of binary using floating-point notation when I have the desired sizes of the mantissa and exponent. – Krokodil Sep 30 '21 at 12:48
  • If you're talking about efficiency, like I said before a better approach would be probably to find a better algorithm rather than optimizing the operations of the same one. In your case you can use this https://stackoverflow.com/questions/4414077/read-write-bytes-of-float-in-js – Gonnen Daube Sep 30 '21 at 12:50
  • 1
    @AlphaHowl I recommend asking this in [code review](https://codereview.stackexchange.com/) they have given me good pointers in the past. – async await Sep 30 '21 at 17:01
  • @asyncawait thank you that is exactly what I needed – Krokodil Sep 30 '21 at 17:05

1 Answers1

0

You can replace Math.round by double negation bitwise ~~

function get_whole_number(number, exponent=0) {
if(number%1 == 0) return [number, exponent];
exponent++;
number *= 2;
if(exponent >= 500) return [~~(number), exponent];
return get_whole_number(number, exponent);};