Java Understanding Math.getExponent(Double) - java

Double dble = new Double("2.2737367544323201e-13");
int exponent = Math.getExponent(dble);
I have the above code and exponent has value of '-43'. I'm not sure how the exponent is '-43', when the passed double value contains '-13'. Could someone shed some light into this API?

Math.getExponent() returns the exponent of the binary representation of the number. In your example -13 is the exponent of the decimal representation, and -43 the exponent of the binary representation.
For example,
System.out.println (Math.getExponent (1024));
prints
10
since
1024 = 2 ^ 10
so the exponent is 10.
System.out.println (Math.getExponent (1.0/8192));
will print
-13
since
1.0/8192 = 2 ^ (-13)

Related

"The literal 0008 of type int is out of range" [duplicate]

I am trying to write following code.but it gives me error kindly help me.
int six=06;
int seven=07;
int abc=018;
int nine=011;
System.out.println("Octal 011 ="+nine);
System.out.println("octal O18 =" + abc);
why i cant give 018 and 019 to variable.i can give value 020 and 021 to variable.
Why this happen? what's the reason behind this Kindly tell me.
I got Following error
integer number too large: 018
int eight=018;
Octal is base-8 number system, so it means digit can be from 0 to 7, you can't use digit 8 (and 9 too) in octal number system.
// Decimal declaration and possible chars are [0-9]
int decimal = 495;
// HexaDecimal declaration starts with 0X or 0x and possible chars are [0-9A-Fa-f]
int hexa = 0X1EF;
// Octal declaration starts with 0 and possible chars are [0-7]
int octal = 0757;
// Binary representation starts with 0B or 0b and possible chars are [0-1]
int binary = 0b111101111;
If the number is string format then you can convert it into int using the below
String text = "0b111101111";
int value = text.toLowerCase().startsWith("0b") ? Integer.parseInt(text.substring(2), 2)
: Integer.decode(text);
why i cant give 018 and 019 to variable.
Because an integer literal prefixed with 0 is treated as octal, and '8' and '9' aren't valid octal digits.
From section 3.10.1 of the JLS:
An octal numeral consists of an ASCII digit 0 followed by one or more of the ASCII digits 0 through 7 interspersed with underscores, and can represent a positive, zero, or negative integer.
Trying to use '8' in an octal number is like trying to use 'G' in hex... it's simple not part of the set of symbols used in that base.
Octal numbers (base 8) can only use the following figures: 01234567. The same way that decimal numbers (base 10) can only use 0123456789.
So in octal representation, 17 + 1 is 20.
The prefix 0 indicates octal(8 base)(digits 0-7).
public class MainClass{
public static void main(String[] argv){
int intValue = 034; // 28 in decimal
int six = 06; // Equal to decimal 6
int seven = 07; // Equal to decimal 7
int eight = 010; // Equal to decimal 8
int nine = 011; // Equal to decimal 9
System.out.println("Octal 010 = " + eight);
}
}
why i cant give 018 and 019 to variable.i can give value 020 and 021 to variable.
The leading zero signifies an octal literal. However, 8 and 9 are not valid octal digits. This makes 018 and 019 invalid.
When an integer literal starts with 0 in Java, it's assumed to be in octal notation. The digits 8 and 9 are illegal in octal—the digits can range only between 0 and 7.
Because it's octal, an octal number has 8 digits which spans from 0 to 7 inclusive. For the same reason 12 would be an invalid binary number.
You need at least base 9 to have 18 and a normal decimal base for 19.
For your query.....you assign an invalid value to the variable....your assigned value is started with 0(zero) ..which means that you are assigning an octal value to the variable and when you assign a value higher then 7 such as 018 in your case...the value excedes the range of octal variables and hence show an error...so try entering simply 18 so it would take it as an integer rather than an octal variable data type...

What are the Java primitive data type modifiers?

Alright, I've been programming in Java for the better part of three years, now, and consider myself very experienced. However, while looking over the Java SE source code, I ran into something I didn't expect:
in class Double:
public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324
I did not expect this and can't find out what it means. If you don't know, I'm referring to the p and P that are after these numbers, before the subtraction operator. I know you can use suffixes to force a number to be a double, long, float, etc., but I've never encountered a p or P. I checked the Java API, but it doesn't mention it. Is there a complete list of Java primitive number literal modifiers somewhere? Does anyone know them all?
For reference, below are the ones I've used or encountered, with the ones whose purposes elude me in bold with question marks (# represents any arbitrary number within respective limits):
Suffixes:
# = 32-bit integer int
#L = 64-bit integer long
#l = another 64-bit integer l?
#f = 32-bit floating-point float
#F = another 32-bit floating-point float?
#d = 64-bit floating-point double
#D = another 64-bit floating-point double?
#e# = scientific notation
#E# = another scientific notation?
#p = ?
#P = ?
Any more?
Prefixes:
0b# = binary (base 2) literal
0B# = another binary (base 2) literal?
0# = octal (base 8) literal
# = decimal (base 10) literal
0x# = hexadecimal (base 16) literal
0X# = another hexadecimal (base 16) literal?
Any more?
Other (are there suffixes or prefixes for these?):
(byte)# = 8-bit integer byte
(short)# = 16-bit integer short
(char)# - 32-bit character char
P is the exponent. It does not matter if it's capital or not.
According to the Javadoc for toHextString (which we know is being used because it begins with 0x:
public static String toHexString(double d) Returns a hexadecimal string representation of the double argument. All characters mentioned below are ASCII characters. If the argument is NaN, the result is the string "NaN". Otherwise, the result is a string that represents the sign and magnitude of the argument. If the sign is negative, the first character of the result is '-' ('\u002D'); if the sign is positive, no sign character appears in the result. As for the magnitude m:
If m is infinity, it is represented by the string "Infinity"; thus, positive infinity produces the result "Infinity" and negative
infinity produces the result "-Infinity".
If m is zero, it is represented by the string "0x0.0p0"; thus, negative zero produces the result "-0x0.0p0" and positive zero produces the result "0x0.0p0".
If m is a double value with a normalized representation, substrings are used to represent the significand and exponent fields. The significand is represented by the characters "0x1." followed by a lowercase hexadecimal representation of the rest of the significand as a fraction. Trailing zeros in the hexadecimal representation are removed unless all the digits are zero, in which case a single zero is used. Next, the exponent is represented by "p" followed by a decimal string of the unbiased exponent as if produced by a call to Integer.toString on the exponent value.
If m is a double value with a subnormal representation, the significand is represented by the characters "0x0." followed by a hexadecimal representation of the rest of the significand as a fraction. Trailing zeros in the hexadecimal representation are removed. Next, the exponent is represented by "p-1022". Note that there must be at least one nonzero digit in a subnormal significand.
According to the JLS, the following pieces of grammar are accepted:
3.10.1. Integer Literals
IntegerTypeSuffix:
l
L
OctalNumeral:
0 OctalDigits
0 Underscores OctalDigits
HexNumeral:
0 x HexDigits
0 X HexDigits
BinaryNumeral:
0 b BinaryDigits
0 B BinaryDigits
3.10.2. Floating-Point Literals
ExponentIndicator: one of
e
E
FloatTypeSuffix: one of
f
F
d
D
HexSignificand:
HexNumeral
HexNumeral .
0 x HexDigitsopt . HexDigits
0 X HexDigitsopt . HexDigits
BinaryExponentIndicator: one of
p
P
No other single character literals are specified for those purposes.
All of the legal ways to declare a literal are defined in the JLS.
p or P is the binary exponent of a number.
l or L defines a long.
f or F defines a float.
d or D defines a double.
0B or 0b defines a binary literal.
0x or 0X defines a hexadecimal literal.
e or E is also an exponent, but since e is a valid character in hexadecimal, p is also used.
P or p is a BinaryExponentIndicator. See the Java language specification.
See http://docs.oracle.com/javase/specs/jls/se5.0/html/lexical.html#3.10.2

trying to convert double presision number to decimal

I'm trying to convert double precision number to decimal .
for example the number 22 in double precision and as bytes are :
[0] 0
[1] 0
[2] 0
[3] 0
[4] 0
[5] 0
[6] 54
[7] 64
now I try to convert these values again to 22 :
ByteBuffer buffer = ByteBuffer.wrap(data);
long l = buffer.getLong();
long b = Double.doubleToLongBits(l);
but the result is something totally wrong :4.6688606E18
what's this number ? please help , I'm totally confused!
according to IEEE Standard 754 for double precision:
Any value stored as a double requires 64 bits, formatted as shown in the table below:
63
Sign (0 = positive, 1 = negative)
62 to 52
Exponent, biased by 1023
51 to 0
Fraction f of the number 1.f
now how should I convert double precision to numbers to get 22 again ? all of these answers are wrong
I'm not sure exactly what sort of conversion you're trying to do (when you say "convert to decimal", what is your desired output format/class?)
However, my first thought reading the title was that a BigDecimal would be a valid representation. So the first approach would be to do something like the following:
double d = ...; // your input number
BigDecimal b = new BigDecimal(d);
That said, if you want to convert to decimal then it's presumably because there are floating ponit/rounding issues with the value of d, which will still be present in the BigDecimal representation as it's being constructed based on d.
The best approach to get around this is to use BigDecimals from the get-go, using their String constructor - so there won't be any instances of floating-point rounding. If this isn't an option for whatever reason, you can convert the double to a string in such a way that it will account for many floating point rounding issues:
String strRep = Double.toString(d);
BigDecimal b = new BigDecimal(strRep);
You can write simple test (with JUnit):
double initial = 22.0;
long bits = Double.doubleToLongBits(initial);
double converted = Double.longBitsToDouble(bits);
assertEquals(Double.valueOf(initial), Double.valueOf(converted));
If this works - check you have correct byte representation for 22 (correct representation will be at bits variable).

why is the Double.parseDouble making 9999999999999999 to 10000000000000000? [duplicate]

This question already has answers here:
How to resolve a Java Rounding Double issue [duplicate]
(13 answers)
Closed 9 years ago.
why is the Double.parseDouble making 9999999999999999 to 10000000000000000 ?
For Example :
Double d =Double.parseDouble("9999999999999999");
String b= new DecimalFormat("#.##").format(d);
System.out.println(b);
IS Printing
10000000000000000
instead it has to show 9999999999999999 or 9999999999999999.00
Any sort of help is greatly appreciated.
The number 9999999999999999 is just above the precision limit of double-precision floating-point. In other words, the 53-bit mantissa is not able to hold 9999999999999999.
So the result is that it is rounded to the nearest double-precision value - which is 10000000000000000.
9999999999999999 = 0x2386f26fc0ffff // 54 significant bits needed
10000000000000000 = 0x2386f26fc10000 // 38 significant bits needed
double only has 15/16 digits of accuracy and when you give it a number it can't represent (which is most of the time, even 0.1 is not accurate) it takes the closest representable number.
If you want to represent 9999999999999999 exactly, you need to use BigDecimal.
BigDecimal bd = new BigDecimal("9999999999999999");
System.out.println(new DecimalFormat("#.##").format(bd));
prints
9999999999999999
Very few real world problems need this accuracy because you can't measure anything this accurately anyway. i.e. to an error of 1 part per quintillion.
You can find the largest representable integer with
// search all the powers of 2 until (x + 1) - x != 1
for (long l = 1; l > 0; l <<= 1) {
double d0 = l;
double d1 = l + 1;
if (d1 - d0 != 1) {
System.out.println("Cannot represent " + (l + 1) + " was " + d1);
break;
}
}
prints
Cannot represent 9007199254740993 was 9.007199254740992E15
The largest representable integer is 9007199254740992 as it needs one less bit (as its even)
9999999999999999 requires 54 bits of mantissa in order to be represented exactly, and double only has 52. The number is therefore rounded to the nearest number that can be represented using a 52-bit mantissa. This number happens to be 10000000000000000.
The reason 10000000000000000 requires fewer bits is that its binary representation ends in a lot of zeroes, and those zeroes can get represented by increasing the (binary) exponent.
For detailed explanation of a similar problem, see Why is (long)9223372036854665200d giving me 9223372036854665216?

How do I convert a decimal fraction to binary in Java?

I need to convert 0.5 in base 10 to base 2 (0.1).
I have tried using
Double.doubleToRawLongBits(0.5)
and it returns 4602678819172646912 which I guess is in hex, but it does not make sense to me.
No. 4602678819172646912 is in dec, hex is 0x3fe0000000000000. To dismantle that:
3 | F | E | 0 ...
0 0 1 1 1 1 1 1 1 1 1 0 0 ...
s| exponent | mantissa
s is the sign bit, exponent is the exponent shifted by 2^9 (hence this exponent means -1), mantissa is the xxx part of the number 1.xxx (1. is implied). Therefore, this number is 1.000...*2^-1, which is 0.5.
Note that this describes the "normal" numbers only, so no zeros, denormals, NaNs or infinities
Multiply you number by 2^n, convert to an BigInteger, convert to binary String, add a decimal point at position n (from right to left).
Example (quick & ++dirty):
private static String convert(double number) {
int n = 10; // constant?
BigDecimal bd = new BigDecimal(number);
BigDecimal mult = new BigDecimal(2).pow(n);
bd = bd.multiply(mult);
BigInteger bi = bd.toBigInteger();
StringBuilder str = new StringBuilder(bi.toString(2));
while (str.length() < n+1) { // +1 for leading zero
str.insert(0, "0");
}
str.insert(str.length()-n, ".");
return str.toString();
}
This is decimal for 0x3FE0_0000_0000_0000. The mantissa is the list of zeros after 3FE (which codes sign and exponent). This is what you are looking for, given that 0.1 before the zeros is implicit.
Do you want to convert the decimal string to floating-point binary or to a binary string? If the former, just use valueOf(); if the latter, use valueOf() followed by toString() or printf().
0.1 is NOT a binary representation of 0.5
Java will represent 0.5 using IEEE 754, as specified on the Java Language Specification. BigInteger.valueOf(Double.doubleToRawLongBits(0.5)).toByteArray() will give you a byte per byte representation of 0.5 as Java does internally.

Categories

Resources