Lorenzo
Lorenzo

Reputation: 45

Base 2 custom method and approximation in Java

I'm writing a method of a Network Calculator that calculates how many bits are needed giving a number of hosts. This is the piece of code that is giving me some problems:

int hostBits = (int) Math.ceil(Math.log(hosts) / Math.log(2));

It works fine with small numbers, but the problem comes up when I enter big ones, like 2^31 - 2, because the result of Math.log(hosts) / Math.log(2) (changing the base of the logarithm), that should be 31.0, actually is 31.000000000000004.

Then, Math.ceil(...) brings 31.000000000000004 to 32 and not to 31 as I want.

Does anyone have an idea how to solve this?

Upvotes: 1

Views: 166

Answers (1)

Samuel Marchant
Samuel Marchant

Reputation: 320

Not the problem.

  1. The problem is only that when a number is divided , for example two different integers (int's) the result particularly with "Math" and log methods is "precision" that it expects may well be required to be some custom level or default level of a primitive type such as double - hence the extra decimal places after the decimal point.

  2. Two points, first, when a number is divided that technically would simply be an integer e.g. 12 / 3 = 6 with math and as a primitive type double it will always have decimal point followed by around six zero's or so and a number other than 0 at the end. Second, it could appear worse from the Math library you could get logarithmic notations from a division not decimal places.

A final point, the Math library does not know what the answer will be until it does it so using double type is an automatic conversion no matter how you write it for safety of precision and data type. Automatic swapping of data types is known as promotion (raising precision int to a float) or demotion (lowering precision double to a float)

And to convert it to an integer it will round up or down by rules of the first following decimal place from the point, so you basically only need to put the answer into a "new Double(primativedoubletype)" object and use its "intValue" method.

NB putting an (int) cast in front of it only ensures that it is an int when assigned (generally from an expression or method) to an int variable, however it is not a way of extracting the value of another type to an int, the primitive type must be converted through its standard java type class object with its primatves converter method.

int hostBits2 = new Double((double)Math.ceil(Math.log(hosts) / Math.log(2)+1e-10)).intValue();

Upvotes: 1

Related Questions