how BigInteger method bitLength() returns 2 when applied on BigInteger "-4"? - biginteger

BigInteger n1= new BigInteger("-4");
System.out.println(n1.bitLength());
How it returns bit length 2? Please explain.

The bitLength method of BigInteger class is used to return the number of bits in the minimal two’s-complement representation of this BigInteger, excluding a sign bit.
The minimal two's complement representation of -4 is "100", by excluding the sign bit we get "00" which is 2 bit long. So it returns 2.

Related

Dart/Flutter: Converting BLE characteristic value to double [duplicate]

I don't have much experience working with these low level bytes and numbers, so I've come here for help. I'm connecting to a bluetooth thermometer in my Flutter app, and I get an array of numbers formatted like this according to their documentation. I'm attempting to convert these numbers to a plain temperature double, but can't figure out how. This is the "example" the company gives me. However when I get a reading of 98.5 on the thermometer I get a response as an array of [113, 14, 0, 254]
Thanks for any help!
IEEE-11073 is a commonly used format in medical devices. The table you quoted has everything in it for you to decode the numbers, though might be hard to decipher at first.
Let's take the first example you have: 0xFF00016C. This is a 32-bit number and the first byte is the exponent, and the last three bytes are the mantissa. Both are encoded in 2s complement representation:
Exponent, 0xFF, in 2's complement this is the number -1
Mantissa, 0x00016C, in 2's complement this is the number 364
(If you're not quite sure how numbers are encoded in 2's complement, please ask that as a separate question.)
The next thing we do is to make sure it's not a "special" value, as dictated in your table. Since the exponent you have is not 0 (it is -1), we know that you're OK. So, no special processing is needed.
Since the value is not special, its numeric value is simply: mantissa * 10^exponent. So, we have: 364*10^-1 = 36.4, as your example shows.
Your second example is similar. The exponent is 0xFE, and that's the number -2 in 2's complement. The mantissa is 0x000D97, which is 3479 in decimal. Again, the exponent isn't 0, so no special processing is needed. So you have: 3479*10^-2 = 34.79.
You say for the 98.5 value, you get the byte-array [113, 14, 0, 254]. Let's see if we can make sense of that. Your byte array, written in hex is: [0x71, 0x0E, 0x00, 0xFE]. I'm guessing you receive these bytes in the "reverse" order, so as a 32-bit hexadecimal this is actually 0xFE000E71.
We proceed similarly: Exponent is again -2, since 0xFE is how you write -2 in 2's complement using 8-bits. (See above.) Mantissa is 0xE71 which equals 3697. So, the number is 3697*10^-2 = 36.97.
You are claiming that this is actually 98.5. My best guess is that you are reading it in Fahrenheit, and your device is reporting in Celcius. If you do the math, you'll find that 36.97C = 98.55F, which is close enough. I'm not sure how you got the 98.5 number, but with devices like this, this outcome seems to be within the precision you can about expect.
Hope this helps!
Here is something that I used to convert sfloat16 to double in dart for our flutter app.
double sfloat2double(ieee11073) {
var reservedValues = {
0x07FE: 'PositiveInfinity',
0x07FF: 'NaN',
0x0800: 'NaN',
0x0801: 'NaN',
0x0802: 'NegativeInfinity'
};
var mantissa = ieee11073 & 0x0FFF;
if (reservedValues.containsKey(mantissa)){
return 0.0; // basically error
}
if ((ieee11073 & 0x0800) != 0){
mantissa = -((ieee11073 & 0x0FFF) + 1 );
}else{
mantissa = (ieee11073 & 0x0FFF);
}
var exponent = ieee11073 >> 12;
if (((ieee11073 >> 12) & 0x8) != 0){
exponent = -((~(ieee11073 >> 12) & 0x0F) + 1 );
}else{
exponent = ((ieee11073 >> 12) & 0x0F);
}
var magnitude = pow(10, exponent);
return (mantissa * magnitude);
}

Dart Convert IEEE-11073 32-bit FLOAT to a simple double

I don't have much experience working with these low level bytes and numbers, so I've come here for help. I'm connecting to a bluetooth thermometer in my Flutter app, and I get an array of numbers formatted like this according to their documentation. I'm attempting to convert these numbers to a plain temperature double, but can't figure out how. This is the "example" the company gives me. However when I get a reading of 98.5 on the thermometer I get a response as an array of [113, 14, 0, 254]
Thanks for any help!
IEEE-11073 is a commonly used format in medical devices. The table you quoted has everything in it for you to decode the numbers, though might be hard to decipher at first.
Let's take the first example you have: 0xFF00016C. This is a 32-bit number and the first byte is the exponent, and the last three bytes are the mantissa. Both are encoded in 2s complement representation:
Exponent, 0xFF, in 2's complement this is the number -1
Mantissa, 0x00016C, in 2's complement this is the number 364
(If you're not quite sure how numbers are encoded in 2's complement, please ask that as a separate question.)
The next thing we do is to make sure it's not a "special" value, as dictated in your table. Since the exponent you have is not 0 (it is -1), we know that you're OK. So, no special processing is needed.
Since the value is not special, its numeric value is simply: mantissa * 10^exponent. So, we have: 364*10^-1 = 36.4, as your example shows.
Your second example is similar. The exponent is 0xFE, and that's the number -2 in 2's complement. The mantissa is 0x000D97, which is 3479 in decimal. Again, the exponent isn't 0, so no special processing is needed. So you have: 3479*10^-2 = 34.79.
You say for the 98.5 value, you get the byte-array [113, 14, 0, 254]. Let's see if we can make sense of that. Your byte array, written in hex is: [0x71, 0x0E, 0x00, 0xFE]. I'm guessing you receive these bytes in the "reverse" order, so as a 32-bit hexadecimal this is actually 0xFE000E71.
We proceed similarly: Exponent is again -2, since 0xFE is how you write -2 in 2's complement using 8-bits. (See above.) Mantissa is 0xE71 which equals 3697. So, the number is 3697*10^-2 = 36.97.
You are claiming that this is actually 98.5. My best guess is that you are reading it in Fahrenheit, and your device is reporting in Celcius. If you do the math, you'll find that 36.97C = 98.55F, which is close enough. I'm not sure how you got the 98.5 number, but with devices like this, this outcome seems to be within the precision you can about expect.
Hope this helps!
Here is something that I used to convert sfloat16 to double in dart for our flutter app.
double sfloat2double(ieee11073) {
var reservedValues = {
0x07FE: 'PositiveInfinity',
0x07FF: 'NaN',
0x0800: 'NaN',
0x0801: 'NaN',
0x0802: 'NegativeInfinity'
};
var mantissa = ieee11073 & 0x0FFF;
if (reservedValues.containsKey(mantissa)){
return 0.0; // basically error
}
if ((ieee11073 & 0x0800) != 0){
mantissa = -((ieee11073 & 0x0FFF) + 1 );
}else{
mantissa = (ieee11073 & 0x0FFF);
}
var exponent = ieee11073 >> 12;
if (((ieee11073 >> 12) & 0x8) != 0){
exponent = -((~(ieee11073 >> 12) & 0x0F) + 1 );
}else{
exponent = ((ieee11073 >> 12) & 0x0F);
}
var magnitude = pow(10, exponent);
return (mantissa * magnitude);
}

Which method is used in Kotlin's Double.toInt(), rounding or truncation?

On the official API doc, it says:
Returns the value of this number as an Int, which may involve rounding or truncation.
I want truncation, but not sure. Can anyone explain the exact meaning of may involve rounding or truncation?
p.s.: In my unit test, (1.7).toInt() was 1, which might involve truncation.
The KDoc of Double.toInt() is simply inherited from Number.toInt(), and for that, the exact meaning is, it is defined in the concrete Number implementation how it is converted to Int.
In Kotlin, the Double operations follow the IEEE 754 standard, and the semantics of the Double.toInt() conversion is the same as that of casting double to int in Java, i.e. normal numbers are rounded toward zero, dropping the fractional part:
println(1.1.toInt()) // 1
println(1.7.toInt()) // 1
println(-2.3.toInt()) // -2
println(-2.9.toInt()) // -2
First of all, this documentation is straight up copied from Java's documentation.
As far as I know it only truncates the decimal points, e.g. 3.14 will become 3, 12.345 will become 12, and 9.999 will become 9.
Reading this answer and the comments under it suggests that there is no actual rounding. The "rounding" is actually truncating. The rounding differs from Math.floor that instead of rounding to Integer.MIN_VALUE it rounds to 0.
use this roundToInt() in kotlin
import kotlin.math.roundToInt
fun main() {
var r = 3.1416
var c:Int = r.roundToInt()
println(c)
}
Use the function to.Int(), and send the value to the new variable which is marked as Int:
val x: Int = variable_name.toInt()

dot notation with p for hexadecimal numeric literals in swift

I'm working through the first basic playground in https://github.com/nettlep/learn-swift using XCode
What exactly is happening with this expression?
0xC.3p0 == 12.1875
I've learned about hexadecimal literals and the special "p" notation that indicates a power of 2.
0xF == 15
0xFp0 == 15 // 15 * 2^0
If I try 0xC.3 I get the error: Hexadecimal floating point literal must end with an exponent.
I found this nice overview of numeric literals and another deep explanation, but I didn't see something that explains what .3p0 does.
I've forked the code and upgraded this lesson to XCode 7 / Swift 2 -- here's the specific line.
This is Hexadecimal exponential notation.
By convention, the letter P (or p, for "power") represents times two
raised to the power of ... The number after the P is decimal and
represents the binary exponent.
...
Example: 1.3DEp42 represents hex(1.3DE) × dec(2^42).
For your example, we get:
0xC.3p0 represents 0xC.3 * 2^0 = 0xC.3 * 1 = hex(C.3) = 12.1875
where hex(C.3) = dec(12.{3/16}) = dec(12.1875)
As an example, you can try 0xC.3p1 (equals hex(C.3) * dec(2^1)), which yields double the value, i.e., 24.375.
You can also study the binary exponent growth in a playground for hex-value 1:
// ...
print(0x1p-3) // 1/8 (0.125)
print(0x1p-2) // 1/4 (0.25)
print(0x1p-1) // 1/2 (0.5)
print(0x1p1) // 2.0
print(0x1p2) // 4.0
print(0x1p3) // 8.0
// ...
Finally, this is also explained in Apple`s Language Reference - Lexical Types: Floating-Point Literals:
Hexadecimal floating-point literals consist of a 0x prefix, followed
by an optional hexadecimal fraction, followed by a hexadecimal
exponent. The hexadecimal fraction consists of a decimal point
followed by a sequence of hexadecimal digits. The exponent consists
of an upper- or lowercase p prefix followed by a sequence of decimal
digits that indicates what power of 2 the value preceding the p is
multiplied by. For example, 0xFp2 represents 15 x 2^2, which
evaluates to 60. Similarly, 0xFp-2 represents 15 x 2^-2, which
evaluates to 3.75.

Algorithm to convert integer (represented as an array) with base n to integer with base m

I have a, very long, integer. The integer is represented by a array of unsigned chars.
Example: the integer 1234 with base 10 is represented in the array as [4,3,2,1], [2,2,3,2] (base 8) and [2,13,4] (base 16)
Now I want to convert my integer with base n to another integer with base m. In my persued for a answer I came accross Wallar's algorithm, originally from here.
from math import *
def baseExpansion(n,c,b):
j = 0
base10 = sum([pow(c,len(n)-k-1)*n[k] for k in range(0,len(n))])
while floor(base10/pow(b,j)) != 0: j = j+1
return [floor(base10/pow(b,j-p)) % b for p in range(1,j+1)]
At first I thought this was my answer but unfortunately it is not. The problem I have is that the algorithm computes the sum. In my case this is a problem because the variable base10 is of type unsigned integer of 32 bits. Therefore when my integer, represented as a array, has more then 10 digits it can not convert the number anymore. Anyone has a solution?
Here's the school-book algorithm for doing what you're trying. You start with a representation for zero and call it a running total. Then, for each digit of the number to be converted, starting with the most significant and going to the least significant, 1) multiply the running total by the base of the source number and 2) add the digit to the running total. Now all you need is algorithms to do the multiplication and addition (and you can actually do both at once). Here's how to do that: 1) set the current digit to a variable, call it "carry", 2) for each digit in your new number, starting with the least significant and going to the most significant: 2a) set carry to the current digit in the new number times the output base plus carry, 2b) set the current digit to carry mod the output base, 2c) set carry to carry divided by the output base. And that should do it. There is an implementation of what you are trying to do somewhere here: http://www.cis.ksu.edu/~howell/calculator/comparison.html