I want to convert signed integer to 32-bit hexadecimal.
The following works fine for positive integer:
format %.8x $the_decimal_value
But for negative integer, I got 64-bit hexadecimal.
For example, 99 is converted to 00000063, but -81 is converted to ffffffffffffffaf.
Anyone know how to get 32-bit hexadecimal from a negative integer?
% set num -81
% format 0x%.8x [expr {$num & 0xFFFFFFFF}]
0xffffffaf
The only hint in the docs I can find is this.
Related
I have a number that I received from a C program that came to me as a negative number:
-1771632774
It's supposed to be this number:
2523334522
I realized that this must be due to some conversion from an signed integer to an unsigned integer. Now that I have this negative number in Ruby, how can I convert it back to the unsigned version?
Put the negative integer in an array. Call pack with an argument of 'L' which represents "32-bit unsigned, native endian (uint32_t)". Call unpack with the same argument. Finally, get the number out of the array.
[-1771632774].pack('L').unpack('L').first
#=> 2523334522
http://ruby-doc.org/core-2.4.0/Array.html#method-i-pack
I am working on GwBasic and want to know how 'CVI("aa")' returns '24929' is that converts each char to ASCII but code of "aa" is 9797.
CVI converts between a GW-BASIC integer and its internal representation in bytes. That internal representation is a 16-bit little-endian signed integer, so that the value you find is the same as ASC("a") + 256*ASC("a"), which is 97 + 256*97, which is 24929.
MKI$ is the opposite operation of CVI, so that MKI$(24929) returns the string "aa".
The 'byte reversal' is a consequence of the little endianness of GW-BASIC's internal representation of integers: the leftmost byte of the representation is the least significant byte, whereas in hexadecimal notation you would write the most significant byte on the left.
I am working with the following HEX values representing different values from a GPS/GPRS plot. All are given as 32 bit integer.
For example:
296767 is the decimal value (unsigned) reported for hex number: 3F870400
Another one:
34.96987500 is the decimal float value (signed) given on radian resolution 10^(-8) reported for hex humber: DA4DA303.
Which is the process for transforming the hex numbers onto their corresponding values on Ruby?
I've already tried unpack/pack with directives: L, H & h. Also tried adding two's complement and converting them to binary and then decimal with no success.
If you are expecting an Integer value:
input = '3F870400'
output = input.scan(/../).reverse.join.to_i( 16 )
# 296767
If you are expecting degrees:
input = 'DA4DA303'
temp = input.scan(/../).reverse.join.to_i( 16 )
temp = ( temp & 0x80000000 > 1 ? temp - 0x100000000 : temp ) # Handles negatives
output = temp * 180 / (Math::PI * 10 ** 8)
# 34.9698751282937
Explanation:
The hexadecimal string is representing bytes of an Integer stored least-significant-byte first (or little-endian). To store it as raw bytes you might use [296767].pack('V') - and if you had the raw bytes in the first place you would simply reverse that binary_string.unpack('V'). However, you have a hex representation instead. There are a few different approaches you might take (including putting the hex back into bytes and unpacking it), but in the above I have chosen to manipulate the hex string into the most-significant-byte first form and use Ruby's String#to_i
How can I convert a double-precision hexadecimal back into a double?
For example, given the string '4045000000000000', how do I get back to the double 42.0?
Pack the hexadecimal into bytes and unpack them as a double:
['4045000000000000'].pack("H*").unpack("G").first # => 42.0
I tried to read from a file where numbers are stored as 16-bit signed integers in big-endian format.
I used unpack to read in the number, but there is no parameter for a 16-bit signed integer in big-endian format, only for an unsigned integer. Here is what I have so far:
number = f.read(2).unpack('s')[0]
Is there a way to interpret the number above as a signed integer or another way to achieve what I want?
I don't know if it's possible to use String#unpack for that, but to convert a 16bit-unsigned to signed, you can use the classical method:
>> value = 65534
>> (value & ~(1 << 15)) - (value & (1 << 15))
=> -2
Use BinData and there's no need for bit twiddling.
BinData::Int16be.read(io)
Found a solution that works by reading two 8bit unsigned integers and convert them to a 16bit big-endian integer
bytes = f.read(2).unpack('CC')
elevation = bytes[0] << 8 | bytes[1]
Apparently since Ruby 1.9.3 you can actually suffix the s with endiannes like so:
io.read(2).unpack('s>')