2

In Java, the bitwise not operator (~) inverts all bits of an integer or long. But why is this not possible for a double? Is there any method of using this operation on a double? I am writing my own programming language in Java (this is NOT a homework assignment), and I believe that bitwise should be included for doubles.

Any ways of using bitwise not on doubles?

EDIT: This is not a duplicate of How to perform a bitwise operation on floating point numbers, because I am using Java as opposed to the discussed C. I also know that there is no possible way using the syntax of the language, but the answers there seem to cast the double to an int. I need to keep the double as it is, without changing it to an int or long.

EDIT: The bitwise not isn't what I thought it would be. It seems to perform *-1 - 1 on the input. Therefore, my question now becomes:

I wish to turn a double into binary (see my other question ), invert all of the bits (0 to 1 and 1 to 0), then convert it back to a double.

Community
  • 1
  • 1
hyper-neutrino
  • 5,272
  • 2
  • 29
  • 50
  • Perhaps you could explain what you expect the negation of `0` to be... in binary as a `double`. – Elliott Frisch Jun 03 '15 at 22:12
  • 1
    What meaning do bitwise operations have for floating-point values? – Matt Ball Jun 03 '15 at 22:13
  • 2
    Well, you could use `Double.doubleToRawLongBits`, negate it, and then `Double.longToDoubleBits`. Doesn't mean much though. – Andy Turner Jun 03 '15 at 22:13
  • 2
    But the result won't *mean* anything. It'll be 'the bitwise inverse of a floating point number', which has no intrinsic or mathematical value. – Jongware Jun 03 '15 at 22:14
  • The inverse of `0` should be `1`. `0` is `0b0`, and the inverse of that is `0b1`. Also, using long bits results in `NaN` most of the time. – hyper-neutrino Jun 03 '15 at 22:15
  • For (signed) integers, adding Not-itself will always result in `-1`. Doing the same with a double will probably only result in garbage. – Jongware Jun 03 '15 at 22:15
  • 1
    @JamesSmith ... so if you think the inverse of 0 should be 1, and the inverse of 1 should be 0, what is the inverse of 3? or 7? or for that matter 2.718 ? – khelwood Jun 03 '15 at 22:22
  • @khelwood I have just found out that the bitwise not isn't quite what I expected. It looks like `~x = (-1 * x) - 1`. – hyper-neutrino Jun 03 '15 at 23:24
  • Just for the principle, I quite agree this is *not* a duplicate of the other suggested question, although it is more or less the same problem indeed. – Bruno Jun 04 '15 at 12:44
  • I have decided that I will not include bitwise operators on doubles, for the reason of recursive decimals losing precision. – hyper-neutrino Jun 04 '15 at 17:51

3 Answers3

8

Java didn't supply the ~ operator on the floating-point types float and double because such an operation isn't meaningful.

You can simulate it with this method:

public static double performNotOnDouble(double d)
{
    return Double.longBitsToDouble(~Double.doubleToLongBits(d));
}

But the results don't have any real meaning:

0.0: NaN
1.0: -3.9999999999999996
10.0: -0.43749999999999994
-1.0: 3.9999999999999996
0.01: -440.31999999999994
3.141592653589793: -1.4292036732051032
2.718281828459045: -1.6408590857704772
Infinity: -2.225073858507201E-308
-Infinity: 2.225073858507201E-308
NaN: -1.1125369292536E-308

There is no point to taking the bit-complement of a floating-point type, because the result doesn't have any meaning.

rgettman
  • 176,041
  • 30
  • 275
  • 357
  • 3
    It probably means something, but it's not obvious what it is – smac89 Jun 03 '15 at 22:18
  • @Smac89 what the answer means is that the result has no *useful* meaning. – user253751 Jun 03 '15 at 22:24
  • 1
    Here is a *practical* reason inverting the bits cannot lead to a meaningful number: in IEEE 754 double precision, "the most significant bit is always 1 for a normalized number, this bit is not typically stored and is called the 'hidden bit'." ([wikipedia](http://en.wikipedia.org/wiki/Significand)) – and you cannot invert what is not there. – Jongware Jun 03 '15 at 23:25
2

You could use Double and convert it using doubleToRawLongBits and then use any bitwise operator you want.

However, I don't know what this will suppose to mean :$ but it will definitely work... Is this what you need?

Cacho Santa
  • 6,846
  • 6
  • 41
  • 73
1

You'd really need to read up about IEEE 754 before considering this sort of operation, and this part of the JLS spec.

The inverse of 0 should be 1. 0 is 0b0, and the inverse of that is 0b1. Also, using long bits results in NaN most of the time.

While 0.0d is indeed 0b0, 0b1 is certainly not the bitwise inverse of 0.0d.

  • Double.doubleToLongBits(0.0d)) = 0
  • Double.doubleToLongBits(1.0d) = 4607182418800017408
  • Double.longBitsToDouble(0b1) = 4.9E-324

In general, each double value really represents a range of values around that value you're able to print out, taking into account some imprecision.

You should also check "How to resolve a Java Rounding Double issue" (and possibly a number of questions that link to it).

Bitwise operations in that context are generally meaningless.

(Along these lines, you can read a bit about strictfp for your general Java knowledge.)

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376