TCL: convert negative integer to hexadecimal? - format

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

How to convert a signed integer to an unsigned integer in Ruby?

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

How MKI$ and CVI Functions works

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.

Convert HEX 32 bit from GPS plot on Ruby

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

Convert the hexadecimal representation of a binary double-precision number back into a double in Ruby

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

Reading a binary 16-bit signed (big-endian) integer in Ruby

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>')

Resources