What is numeric promotion? - java

Can any one tell what is numeric promotion?

Numeric promotion is the conversion of a smaller numeric type to a larger numeric type, so that integer and floating-point operations may take place. In numerical promotion, byte, char, and short values are converted to int values. The int values are also converted to long values, if necessary. The long and float values are converted to double values, as required.

Numeric Promotion Rules
If two values have different data types, Java will automatically promote one of the values to the larger of the two data types.
If one of the values is integral and the other is floating-point, Java will automatically promote the integral value to the floating-point value’s data type.
Smaller data types, namely byte, short, and char, are first promoted to int any time they’re used with a Java binary arithmetic operator, even if neither of the operands is int.
After all promotion has occurred and the operands have the same data type, the resulting value will have the same data type as its promoted operands

Numeric promotion is a conversion of an operand (at least one of the numbers involved) to a common type.
For example:
int i = 10;
double d1 = 2.5;
double d2 = d1 * i;
In this case, i is promoted to double so the calculation can be performed. In some ways, you can think of this is analogous to boxing, but boxing involves moving from a struct to an object (from the stack to the heap). But, using the analogy does give an idea of the fact the integral value is being made into a floating point to perform the calculation.

If you look here, you will see the following quote:
Numeric promotion (§5.6) brings the
operands of a numeric operator to a
common type so that an operation can
be performed.
They are referencing this section, where they give a variety of examples. The classic example is that of an int times a float. The integer is promoted to a float so that the multiplied result is, therefore, a float.

Related

Customized Base64 algorithme [duplicate]

Can any one tell what is numeric promotion?
Numeric promotion is the conversion of a smaller numeric type to a larger numeric type, so that integer and floating-point operations may take place. In numerical promotion, byte, char, and short values are converted to int values. The int values are also converted to long values, if necessary. The long and float values are converted to double values, as required.
Numeric Promotion Rules
If two values have different data types, Java will automatically promote one of the values to the larger of the two data types.
If one of the values is integral and the other is floating-point, Java will automatically promote the integral value to the floating-point value’s data type.
Smaller data types, namely byte, short, and char, are first promoted to int any time they’re used with a Java binary arithmetic operator, even if neither of the operands is int.
After all promotion has occurred and the operands have the same data type, the resulting value will have the same data type as its promoted operands
Numeric promotion is a conversion of an operand (at least one of the numbers involved) to a common type.
For example:
int i = 10;
double d1 = 2.5;
double d2 = d1 * i;
In this case, i is promoted to double so the calculation can be performed. In some ways, you can think of this is analogous to boxing, but boxing involves moving from a struct to an object (from the stack to the heap). But, using the analogy does give an idea of the fact the integral value is being made into a floating point to perform the calculation.
If you look here, you will see the following quote:
Numeric promotion (§5.6) brings the
operands of a numeric operator to a
common type so that an operation can
be performed.
They are referencing this section, where they give a variety of examples. The classic example is that of an int times a float. The integer is promoted to a float so that the multiplied result is, therefore, a float.

How type extension occurs in case of positives and negatives in Java?

Is there any difference between how type conversion happens in case of positive and negative numbers?
For example, if we have
short a = 100;
and put it to
int b = a;
if we change '100' to '-100', does it make any difference?
I tried to find it compiling in IDEA, but didn't find difference, but I have this questions from my mentor.
Disclaimer: Since this is a homework question, what I say here might not be the "expected" answer.
There are two conversions involved here. The first one is a narrowing primitive conversion from int (the literal 100 evaluates to a value of type int) to short. The second one is a widening primitive conversion from short to int.
The second conversion will never lose information, as per the JLS §5.1.2:
A widening primitive conversion does not lose information about the
overall magnitude of a numeric value in the following cases, where the
numeric value is preserved exactly:
from an integral type to another integral type
from byte, short, or char to a floating point type
from int to double
from float to double in a strictfp expression (§15.4)
The first conversion is done like this, according to the JLS §5.1.3
A narrowing conversion of a signed integer to an integral type T
simply discards all but the n lowest order bits, where n is the number
of bits used to represent type T. In addition to a possible loss of
information about the magnitude of the numeric value, this may cause
the sign of the resulting value to differ from the sign of the input
value.
Both -100 and 100 is representable with short, whose range is -65536...65535, so no information is lost here either.
In short, it doesn't matter whether you use 100 or -100, the result will be that b will store the value of 100 or -100 respectively.

How does Java handle precision across multiple types?

In Java when I print something like this
System.out.println(1.0f*1l));
I get an output of
1.0
or with
System.out.println(((byte)1)*'A');
I get an output of
65
In both cases, one of the types is bigger than the other. Longs are 64-bits while floats are 32-bits, and bytes are 8-bits while chars are 16-bits. Despite this, Java outputs the result in the smaller type. Wouldn't this be considered a loss of precision?
Java Language Specification provides a list of rules governing the type of result based on the types of operands.
In particular, section 4.2.4 says that
If at least one of the operands to a binary operator is of floating-point type, then the operation is a floating-point operation, even if the other is integral.
which explains why float "wins" against a long.
Integer arithmetic is explained in section 5.6.2. Specifically, it says that
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
• If either operand is of type double, the other is converted to double.
• Otherwise, if either operand is of type float, the other is converted to float.
• Otherwise, if either operand is of type long, the other is converted to long.
• Otherwise, both operands are converted to type int.
That is why in your second example the result, 65, is of type int.
Java widens type based on the range of possible values. This means float is considered wider thanlong.
Also integer operations which are not long are performed as int.
A byte * char is an int
You are asking about Binary Numeric Promotion (JLS 5.6.2) (emphasis mine):
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
The expression 1.0f*1l is a float and long, so the long is converted to a float.
The expression ((byte)1)*'A' is a byte and a char, so they are both converted to int.
In addition to the other answers that spell out the rules in detail, I think it's also worth considering why it should be this way. Suppose you do
2.7F * 2L
The true mathematical answer to this multiplication is 5.4. Therefore if the answer were a long, it would have to be 5L (5 is the closest integer to 5.4). Because of this kind of thing it makes much more sense for the result of multiplying a floating-point value by an integer to be a floating point value. I think there would be many more questions about this on Stack Overflow if the following line of code printed 5.
System.out.println(2.7F * 2L);
In fact it prints 5.4.
It also makes sense that all operations between integer types (except long) are done with int. After all, a byte is usually thought of as a small packet of data, and a char is usually thought of as a character. From these perspectives multiplying byte or char values isn't really meaningful. It makes much more sense to keep the rules simple and just do the operations with int.

How to perform unassigned sum with short variable with out converting in to integer in java

My requirement is to perform unassigned sum with short variables in java with out converting in to integer.
Please suggest is it possible to perform unassigned sum or not.
Java doesn't have an addition operator for short values. If you look at JLS 15.18.2 (Additive Operators (+ and -) for Numeric Types) you'll see that one of the first things that happens is:
Binary numeric promotion is performed on the operands (§5.6.2).
That will always convert short values into int, float, long or double values, depending on the other operand.
Basically, to perform 16-bit addition, you let the compiler convert both operands into 32 bits, do the addition, and then cast back:
(short) (a + b)
... being aware that this may lose information due to overflow when casting.

explicit use of l for Long,D for Double,,F for Float in autoboxing

Byte byte1=10;
Short short1=20;
Integer integer=30;
In the above code autoboxing happens successfully
see the below code here I am doing casitng explicitly because It is taking 20 as integer numeric literal by default.
Byte byte1=new Byte((byte) 20);
Short short1=new Short((short) 20);
but see the below code , I have to use l,f and d explicitly without this it is showing error........what is the reason behind it.I am not getting it.
Long long1=40l;
Float float1=50f;
Double double1=60d;
Auto-boxing doesn't include automatic widening of primitives.
The default type of a constant integer numeric expression in java is int, so those numbers are ints, which will be auto boxed to Integers if required. Automatic widening will occur when a narrower primitive type is assigned to a wider type, such as an int to a long.
But the two compiler actions will not both happen; that's why you need to get the primitive constant expression to the appropriate type so that the auto boxing will be to the correct type.
This is part of the Language Specification for floating point literals, ie. F or f for float, and D or d for double
For decimal floating-point literals, at least one digit (in either the
whole number or the fraction part) and either a decimal point, an
exponent, or a float type suffix are required.
For integers,
An integer literal is of type long if it is suffixed with an ASCII
letter L or l (ell); otherwise it is of type int (§4.2.1).
The unboxing conversions are, among other,
From type long to type Long
From type float to type Float
From type double to type Double
So unless your types are the correct type, you cannot unbox.
As for the Byte, Short, Integer, the JLS again comes to the rescue
A narrowing conversion of a signed integer to an integral type T
simply discards all but the n lowest order bits, where n is the number
of bits used to represent type T. In addition to a possible loss of
information about the magnitude of the numeric value, this may cause
the sign of the resulting value to differ from the sign of the input
value.
In your case, an explicit cast isn't necessary because the values fall within the range of their specific type. If instead, you had
Byte b = 1251;
that would create a compilation error, solved by doing
Byte b = (byte)1251;
but losing information in the value.

Categories