Parse signed number from hex using BigInt - scala

I'm trying to parse a signed number using a BigInt. Here have been my attempts
scala> -1.toHexString
res7: String = ffffffff
scala> val bigInt = BigInt(res7,16)
bigInt: scala.math.BigInt = 4294967295
Is there any way to easily parse a signed number from a hex using BigInt?

If your hex string began life as an Integer or a Long—before converting it to a BigInt—parse it as an unsigned number with
java.lang.Integer.parseUnsignedInt("ffffffff",16) // Results in -1
or
java.lang.Long.parseUnsignedLong("ffffffffffffffff",16) // Results in -1

You have to tell it how long your number is one way or another. Without it, just saying "ffffffff" is ambiguous: as an Int it is -1, but as a long it is a large positive value:
bigInt.toLong
res48: Long = 4294967295
bigInt.toInt
res49: Int = -1

Related

Difference between Int and Uint8 swift

What are the differences between the data types Int & UInt8 in swift.
Looks like UInt8 is used for binary data, i need to convert UInt8 to Int is this possible.
That U in UInt stands for unsigned int.
It is not just using for binary data. Uint is used for positive numbers only, like natural numbers.
I recommend you to get to know how negative numbers are understood from a computer.
Int8 is an Integer type which can store positive and negative values.
UInt8 is an unsigned integer which can store only positive values.
You can easily convert UInt8 to Int8 but if you want to convert Int8 to UInt8 then make sure value should be positive.
UInt8 is an 8bit store, while Int not hardly defined or defined by the compiler:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html
Int could be 32 or 64 bits
Updated for swift:
Operation Output Range Bytes per Element
uint8 0 to 255 1
Int - 9223372036854775808 to 9223372036854775807 2 or 4
If you want to find the max and min range of Int or UInt8:
let maxIntValue = Int.max
let maxUInt8Value = UInt8.max
let minIntValue = Int.min
let minUInt8Value = UInt8.min
If you want to convert UInt8 to Int, used below simple code:
func convertToInt(unsigned: UInt) -> Int {
let signed = (unsigned <= UInt(Int.max)) ?
Int(unsigned) :
Int(unsigned - UInt(Int.max) - 1) + Int.min
return signed
}

Scala: insert Long into BigInt using bit shifting

What I want to do to insert the current timestamp into a number of type BigInt. Everything in the BigInt should be shifted to the left to make room for the timestamp. However, leading zeros of the time stamp should be ignored.
What I'm doing at the moment:
val number: BigInt = ...
val time = System.currentTimeMillis
val usedBits = 64 - java.lang.Long.numberOfLeadingZeros(time )
val newNumber = (number << usedBits) | t
Is there a better way to do this? Especially the third line does not seem to be very elegant.
I'm not sure I followed what/why you are doing the shift with a BigInt, but you can use Strings to define BigInts and that might get you closer to what you want.
For example you had:
val number:BigInt = 999 // guessed a number
val time = System.currentTimeMillis // results in Long = 1465400383430
val usedBits = 64 - java.lang.Long.numberOfLeadingZeros(time) // results in Int = 41
val newNumber = (number << usedBits) | time // results in BigInt = 2198289632679878
You could instead change the last line to:
val newNumber2 = BigInt( number.toString + time.toString ) // BigInt = 9991465400383430
To delve int to the difference (it's only 3 bits):
newNumber.bitLength = 51
newNumber2.bitLength = 54
and the binary
newNumber.toLong.toBinaryString = " 111110011110101010100110000101010110101011111000110"
newNumber2.toLong.toBinaryString = "100011011111110010111101010001111110011011011111000110"
Until today, I would have not considered using BigInt to pack bits. But at least in this case it does the job quite well and as a bonus if you use the second method and if you know the length of your numeric strings the values can be extracted easily. Cool :-)

How to convert Mac address as String format to Long in scala?

my question is converting string to long in scala.
where string is format as Mac Address.
for eg:
"fe:1a:90:20:00:00" and "a0:b4:ac:c0:00:01"
How to convert in long type using scala.
This may help:
mac.split(":").map(Integer.parseInt(_,16)).foldLeft(0L) {case (acc,item) => acc*256+item}
First operation
mac.split(":")
gives Array of strings, like Array("fe","1a","90","20","00","00"). Each item of this array is base-16 encoded integer, so we can convert it to array of integers with:
val arrayOfInts = mac.split(":").map(Integer.parseInt(_,16))
which gives for first example Array(254, 26, 144, 32, 0, 0).
The last thing to do is to convert array of integers to long. Each item of array is in range [0,255], so multiplication on 256 is exactly enough to hold the value, last operation
arrayOfInts.foldLeft(0L) {case (acc,item) => acc*256+item}
does the conversion. It starts from 0L and for each item multiplies result on 256 and adds item:
(((((((0L*256 + 254)*256 + 26)*256) + 144)*256 + 32)*256 + 0)*256) + 0
I found the answer in github:
https://github.com/ppurang/flocke/blob/master/core/src/main/scala/org/purang/net/flocke/MacAddress.scala
You could use java library
def hex2Long(hex: String, removeDelimiter: String = ""): Long = {
java.lang.Long.valueOf(hex.replaceAll(removeDelimiter, ""), 16)
}
scala> hex2Long("00:00:00:00:2f:59")
res2: Long = 12121

How do I convert a 50 digit string into the appropriate integer type in Swift?

I need to convert this 50 digit string 53503534226472524250874054075591789781264330331690 into the appropriate number type. I tried this:
let str = "53503534226472524250874054075591789781264330331690"
let num = str.toInt(); // Returns nil
let num = Int64(str.toInt()); // Errors out
The maximimum size of an Int64 is 9,223,372,036,854,775,807 when it is signed. So you cannot convert it just like that.
You need something like the BigInt class found in other languages. Check this other question where they answer with alternatives about BigInt in Swift:
BigInteger equivalent in Swift?
In summary, there are third-party libraries out there for arbitrary long integers. The only alternative from Apple is NSDecimalNumber but its limit is 38 digits, whereas your number has 50.

how does compare two different type of objects in scala?

When i am checking values inside scala interpreter like:
scala> 1==1.0000000000000001
res1: Boolean = true
scala> 1==1.000000000000001
res2: Boolean = false
Here I am not getting clear view related with "how does scala compiler interpret these as integer or floating points or doubles(and comparing)" .
It is not really Scala related, it is more of a ieee-754 floating-point arithmetic issue. First of all when comparing Int with Double it will cast Int to Double (always safe). The second case is obvious - values are different.
What happens with the first case is that Double type is not capable of storing that many significant digits (17 in your case, 64-bit floating point can store up-to 16 decimal digits) so it rounds the value to 1. And 1 == 1.