1

Given any number, for example 345.678 and -345.678, what I want is to convert 345.678 to 1 and -345.678 to -1. Basically I want to convert any number to 1 or -1 with the sign kept via bit-wise operator.

Although I don't know why, I can convert any number into -1 like this:

345.678 | -1

Any thoughts?

krave
  • 1,629
  • 4
  • 17
  • 36
  • 1
    Do you *have* to use bitwise operations to convert and keep the sign? – VLAZ Jul 03 '19 at 12:53
  • 2
    Why not a simple ternary operation like `(value > 0) ? 1 : -1`? – Manav Jul 03 '19 at 12:54
  • 1
    Definitely non-trivial, given that bitwise operators convert the 64 bit floating point number to a 32 bit integer by chopping off the most significant bits. – Robby Cornelissen Jul 03 '19 at 12:55
  • Minus one is made of 1s in binary, that's why the result of `number | -1` is always -1 – Gabriel Hautclocq Jul 03 '19 at 13:01
  • I doubt there is a way to get sign using single bitwise operator. Check this answer https://stackoverflow.com/a/7341458/351705 this might work for you. But it involves shifts and arithmetic operators. – Yury Tarabanko Jul 03 '19 at 13:16
  • I'm inclined to say that it's not possible using only bitwise operators. Look forward to someone proving me wrong. – Robby Cornelissen Jul 03 '19 at 13:19
  • @RobbyCornelissen it *should* be...I think. But I can't figure it out - my brain is currently melting. Thinking about bitwise operations doesn't help that, either. – VLAZ Jul 03 '19 at 13:20
  • @RobbyCornelissen Using OP's requirements (ie ignoring 0 case) the solution would be `const sign = x => x >> 31 | (~x >> 31 & 1); console.log([-323.23, 0, 2343.4].map(sign))` – Yury Tarabanko Jul 03 '19 at 13:24
  • @YuryTarabanko worth posting as an answer, I think. – VLAZ Jul 03 '19 at 13:25
  • @VLAZ Or closing as duplicate. I've simple used C solution from this answer https://stackoverflow.com/a/7341458/351705 :) – Yury Tarabanko Jul 03 '19 at 13:27
  • Anyway Yury's answer has the same limitations as mine for range -1 > x > 0. – Gabriel Hautclocq Jul 03 '19 at 13:33

2 Answers2

2

You could take the idea of this question sign function in C using bit operators only

(x >> 31) & 1

and adjust the result by taking bitwise OR instead of bitwise AND to get 1 instead of 0 and -1 instead of 1

const sign = x => (x >> 31) | 1;

console.log(sign(345.678));
console.log(sign(-345.678));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

For any integer N in the [-2147483648, +2147483647] interval, you can do:

(N >> -1) | 1

It will result in -1 if N is negative, and 1 if N is positive. For zero, the resulting value is 1.

Note:

It does not work for decimals in interval (-1, 0) (the resulting value is 1 instead of -1). However it should work for any other decimal numbers.

If you want it to work for every decimal numbers, the fix is simple:

(Math.floor( N ) >> -1) | 1

But then you're not using only bitwise operators.

Gabriel Hautclocq
  • 3,230
  • 2
  • 26
  • 31