Java 8 Unsigned Integer Addition and Potential Overflow - numbers

I'm working exercises from the book "Java SE 8 for the Really Impatient" by Cay S. Horstmann. One of the exercises based on the improvements in the Number classes asks:
Write a program that adds, subtracts, divides, and compares numbers
between 0 and 232 - 1, using int values and unsigned
operations. Show why divideUnsigned and remainderUnsigned are
necessary.
The problem is, if you add 2 unsigned ints, the sum may overflow the integer limit. I don't see a way to prevent that without using a long to store the sum and checking if it's greater than Integer.MAX_VALUE. Is it possible to do this using ints only?

The Two's complement used for integer values has the neat property that for adding and subtracting it is irrelevant whether you interpret the values as signed or unsigned.
Therefore, even at CPU level, there are no distinct instructions for adding/subtracting signed or unsigned numbers. It’s all about interpretation.
So when you add or subtract two unsigned numbers using the signed int type, the result may overflow in the signed int range. But when printing the now-negative number using Integer.toUnsignedString the result will be the correct unsigned value, assuming that the operation didn’t even overflow in the unsigned integer value range.
That’s why the class java.lang.Integer provides special unsigned operations only where necessary, i.e. for comparing two unsigned values, for division and remainder and for conversions from and to String (and to long, while a type-cast from long to int is already sufficient for the other direction).

In order to obtain an unsigned int, you need to use the Integer.parseUnsignedInt() functions or do a manual calculation. Remember, Java doesn't actually HAVE unsigned integers, Java8 just provides the ability to treat an int as unsigned in order to allow for a greater range of positive-number values.
According to the Java 8 Doc for the Integer class,
An unsigned integer maps the values usually associated with negative
numbers to positive numbers larger than MAX_VALUE
So the conversion between an unsigned int and a signed one is that if the number is greater than or equal to zero AND less than or equal to Integer.MAX_VALUE, it remains the same. If it's greater than Integer.MAX_VALUE but still within the unsigned range, then to store it in an int, you need to add 2^31 to it, which will convert it to the correct value due to the way that addition overflow is defined as an operation. Overflow and underflow in addition of binary primitives like int just causes the counter to reset and continue counting.
int min = Integer.MIN_VALUE; // -2147483648
int max = Integer.MAX_VALUE; // 2147483647
int overByOne = Integer.MAX_VALUE + 1; // -2147483648 : same as Integer.MIN_VALUE
int underByOne = Integer.MIN_VALUE - 1; // 2147483647 : same as Integer.MAX_VALUE
They exercise is just asking you to look at the Integer class and test out the various (new in Java8) methods for unsigned operations. Java does not have unsigned integer primitives, but an int value can be treated as unsigned for the purposes of certain new methods in the Integer class.

Related

PureScript - Convert a number to an integer?

PureScript contains a method in the Integer library fromNumber.
Here is an example of how it might be used:
myInteger = fromMaybe 0 (fromNumber myNumber)
However the docs provide this puzzling explanation:
Creates an Int from a Number value. The number must already be an integer and fall within the valid range of values for the Int type otherwise Nothing is returned.
Basically, your number must already be an Integer to convert it to an integer.
Assuming your number is not already an integer, a reasonable use case, how would you convert it to a number?
If it's not already an integer, there is no one true way of converting it to an integer. You could round to the nearest integer, round up, round down, do banker's rounding, or some sort of crazy conversion scheme of your own.
The Data.Int module offers several functions for different conversion strategies, such as floor, ceil, and round.

How does an "int" represent a byte (8 bits) when an int is normally 32 or 64 bits?

I'm curious how in the Dart programming language a byte is represented by the int type. I am is confusing because in Java, which Dart closely resembles, an int is 32 bits.
I ask because the leading flutter ble library, Flutter Blue, seems to handle List<int> while handling the ble bytes.
However according to the official documentation:
https://flutter.dev/docs/development/platform-integration/platform-channels#codec
Uint8List is used - which is what makes sense the byte[] equivalent.
It seems as those the unsigned 8 bit integers are just then converted to a 32 bit signed int going from Uint8List -> List<int> ? i.e. decimal 2 is is then converted from 00000010 to 00000000000000000000000000000010?
It seems this has ramifications if one would like to write a byte stream. Would need to cast the int's to Uint8's.
The Dart int type is a 64-bit two's complement number—except when compiled for the web, there it's a 64-bit floating point number with no fractional part (a JavaScript number which has an integer value).
How those values are represented internally depends on optimizations, they can be represented as something smaller if the runtime system knows for sure that the value will fit. That's an optimization, you won't be able to tell the difference.
A "byte" value is an integer in the range 0..255. You can obviously store a byte value in an int.
The most efficient way to store multiple bytes is a Uint8List, which implements List<int>. It stores each element as a single octet.
When you read a value out of a Unit8List, its byte value is represented by an int. When you store an int in the Uint8List, only the low 8 bites are stored.
So it does expanding reads and truncating writes to move values between an octet and a 64-bit value.
The size of an int in dart is not completely predictable for local variables as Irn mentions here. The size of the int may be reduced as an optimization if it is seen as possible.
If you do an explicit conversion from Uint8List to List<int> that creates a new List object, the new object will have int elements that are a larger size than 8 bits. Possibly 32 bits, maybe 64 bits, maybe less. The compiler will choose based on what it sees. According to the int class, the default is a signed 64 bit integer.
If you are trying to get from ints to a Uint8List, each int will be truncated to 8 bits.
First, let's clear up one thing. An int is not inherently 32-bits or 64-bits universally. That's just a convention put in place by common languages, including Java. In C, for example, the size of int is an implementation detail that depends on the compiler, the architecture, and the size of a memory address, so it could be 8, 16, 32, or 64 bits (or on more esoteric platforms, something else entirely, like 24 bits). So the notion that Dart is doing something "wrong" by not having int be a 32-bit integer type is somewhat absurd.
Now that that, is out of the way, an int in Dart is not a fixed data type. Like C, it depends on the platform that it is running on.
Mobile: int is a 64-bit integer
Web: int is mapped to the JavaScript Number which is a 64-bit floating point (i.e. double)
Other: int can be defined as an implementation detail
And that's it. Dart has no concept of any other integral type. (i.e. There's no such thing as a byte, short, char, long, long long, etc. as primitive types.)
What you are seeing in Uint8List is an abstraction over a list of 64-bit integers to make it appear like a list of bytes. I'm not sure how it is represented internally (either each "byte" is its own int, using bit-flags to store 8 bytes worth of information in a single int, or it's a native implementation doing something else entirely), but at the end of the day it doesn't really matter.
Uint8List derives from List<int>; passing a Uint8List where a List<int> is expected does not change the representation of the data.
When you read a single int from a Uint8List (e.g. with operator []), you'll get a copy of the octet widened to whatever int is.
When you write an int to a Uint8List (e.g. with operator []=), the stored value will be truncated to include only the lower 8-bits.
There shouldn't be any confusion as to how an int can be used to represent bytes because it all comes down to bits and how you store and manipulate them.
For the sake of simplicity, let us assume that an int is larger than a byte - an int is 32 bits, and a byte is 8 bits. Since, we are dealing with just bits at this point, you can see it is possible for an int to contain 4 bytes because 32/8 is 4 i.e. we can use an int to store bytes without loosing information.
It seems as those the unsigned 8 bit integers are just then converted to a 32 bit signed int going from Uint8List -> List ? i.e. decimal 2 is is then converted from 00000010 to 00000000000000000000000000000010?
You could do it that way, but from I said previously, you can store multiple bytes in an int.
Consider if you have the string Hello, World!, which comes up to 13 bytes and you want to store these bytes in a list of ints, given each int is 32 bits; We only need to use 4 ints to represent this string because 13 * 8 is 104 bits, and four 32bit ints can hold 128 bits of information.
It seems this has ramifications if one would like to write a byte stream. Would need to cast the int's to Uint8's.
Not necessarily.
A byte stream consisting of the bytes 'H', 'e', 'l', 'l', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' can be written into a data structure known as a Bit Array. The bit array for the above stream would look like:
[01001000011001010110110001101100011011110010110000100000010101110110111101110010011011000110010000100001]
Or a list of 32 bit ints:
[1214606444,1865162839,1869769828,33]
If we wanted to convert this list of ints back to bytes, we just need to read the data in chunks of 8 bits to retrieve the original bytes. I will demonstrate it with this simply written dart program:
String readInts(List<int> bitArray) {
final buffer = StringBuffer();
for (var chunk in bitArray) {
for (var offset = 24; offset >= 0; offset -= 8) {
if (chunk < 1 << offset) {
continue;
}
buffer.writeCharCode((chunk >> offset) & 0xff);
}
}
return buffer.toString();
}
void main() {
print(readInts([1214606444,1865162839,1869769828,33]));
}
The same process can be followed to convert the bytes to integers - you just combine every 4 bytes to form a 32 bit integer.
Output
Hello, World!
Of course, you should not need to write such a code by yourself because dart already does this for you in the Uint8List class

Why is the product of two positive integers a negative integer?

This semester i took system proramming course.
Why 50000*50000 will be negative?
I try to understand logic of this.
Here is the screenshot of the slide
slide image
32-bit signed integers are stored by using bits 0-30 as the number and bit 31 indicating the sign of the number.
This means that the maximum value that can be represented is 2,147,483,647 (all bits from 0-30 are set, bit 31 is 0 indicating a positive number).
The product of 50,000 and 50,000 is 25,000,000,000 is greater than this number and you have what is called an overflow. This means that data has "overflowed" from its expected bounds (the bottom 31 bits) into the sign bit).
You now have bit 31 set, indicating that this is a negative number. To figure out a negative number from its binary representation, you take the ones' complement (flip all the bits), add one and then throw a negative sign in front of it.
Be careful when you take the ones' complement that you limit yourself to a 32-bit range... you shouldn't be including bits higher than bit 31.
Check out signed number representations for more information.
Sample Program Pseudo Code
Print --> ("Size of int: " + (Integer.SIZE/8) + " bytes.");
int a=50000;
int b=50000;
Print --> (" Product of a and b " + a*b);
Output :
Size of int: 4 bytes.
Product of a and b:-1794967296
Analysis :
4 bytes= 4*8= 32bits.
Since signed int can hold negative values, one-bit is used for sign (- or +), so bits available for numeric range=31.
Number range = -(2^31) , 0 and (2^31-1)
[one positive number is sacrificed for 0]
-2147483648, 0 and 2147483647
Maximum possible positive int = 2147483647 (greater than 1600000000, so 40000*40000 is fine)
Actual Product 50000*50000=2500000000 (greater than 2147483647)
In practice many portable C programs assume that signed integer overflow wraps around reliably using two's complement arithmetic.
Yet the C standard says that program behavior is undefined on overflow, and in a few cases C programs do not work on some modern implementations because their overflows do not wrap around as their authors expected.
http://www.gnu.org/software/autoconf/manual/autoconf-2.62/html_node/Integer-Overflow.html
This is because in most programming languages, the integer data type has a fixed size.
That means that each integer value have a defined MIN and MAX value.
For example in C# MAX INT is 2147483647 and MIN is -2147483648
In PHP 32 bits it's 2147483647 and -2147483648
In PHP 64 bits it's 9223372036854775807 and -9223372036854775808
What happen when you try to go over that value? Simply the computer will make what's called an integer overflow and the value will loop back to the min value.
In other words, in C# 2147483647 + 1 = -2147483648 (assuming you use an integer datatype, not long or float). That exactly what happen with 50000 * 50000, it just goes over max value and loop from the next value.
The exact min and max values are dependent on the language used, the platform the code is built, the platform the code is run on and the static type of the value.
Hope it clears everything out for you!

Precise division of doubles representing integers exactly (when they are divisible)

Given that 8-byte doubles can represent all 4-byte ints precisely, I'm wondering whether dividing a double A storing an int, by a double B storing an int (such that the integer B divides A) will always give the exact double corresponding to the integer that is their quotient? So, if B and C are integers, and B*C fits within a 32-bit int, then is it guaranteed that
int B,C = whatever s.t. B*C does not overflow 32-bit int
double(B*C)/double(C) == double((B*C)/C) ?
Does the IEEE754 standard guarantee this?
In my testing, it seems to work for all examples I've tried. In Python:
>>> (321312321.0*3434343.0)/321312321.0 == 3434343.0
True
The reason for asking is that Matlab makes it hard to work with ints, so I often just use the default doubles for integer calculations. And when I know that the integers are exactly divisible, and if I know that the answer to the present question is yes, then I could avoid doing casts to ints, idivide(..) etc., which is less readable.
Luis Mendo's comment does answer this question, but to specifically address the use in Matlab there are some handy utilities described here. You can use eps(numberOfInterest) to find the distance to the next largest double-precision floating point number. For example:
eps(1) = 2^(-52)
eps(2^52) = 1
This practically guarantees that mathematical operations with integers held in a double will be precise provided they don't overflow 2^52, which is quite a bit larger than what is held in a 32-bit int type.

How to use Bitxor for Double Numbers?

I want to use xor for my double numbers in matlab,but bitxor is only working for int numbers. Is there a function that could convert double to int in Matlab?
The functions You are looking for might be: int8(number), int16(number), uint32(number) Any of them will convert Double to an Integer, but You must pick the best one for the result You want to achieve. Remember that You cannot cast from Double to Integer without rounding the number.
If I understood You correcly, You could create a function that would simply remove the "comma" from the Double number by multiplying your starting value by 2^n and then casting it to Integer using any of the functions mentioned earlier, performing whatever you want and then returning comma to its original position by dividing the number by 2^n
Multiplying the starting value by 2^n is a hack that will decrease the rounding error.
The perfect value for n would be the number of digits after the comma if this number is relatively small.
Please also specify, why are You trying to do this? This doesn't seem to be the optimal solution.
You can just cast to an integer:
a = 1.003
int8(a)
ans =
1
That gives you an 8 bit signed integer, you can also get other size i.e. int16 or else unsigned i.e. uint8 depending on what you want to do