How to declare 8-bit unsigned integer in ruby?
Ruby abstracts away the internal storage of integers, so you don't have to worry about it.
If you assign an integer to a variable, Ruby will deal with the internals, allocating memory when needed. Smaller integers are of type Fixnum
(stored in a single word), larger integers are of type Bignum
.
a = 64
a.class #=> Fixnum; stored in a single word
a += 1234567890
a.class #=> Bignum; stored in more than a single word
Ruby is dynamically typed, so you cannot force a variable to contain only unsigned 8-bit integers (just as you cannot force a variable to only contain string values, etc.).
Using ruby to convert unsigned integers stored as signed back to the original value
I'm not sure of Ruby specifics, but essentially you need to add 2^64 if the number is negative. That's assuming the number is stored as 2's complement, which it almost certainly is.
FYI, the 2's complement system, essentially it treats a (say) 32-bit number as a number mod 2^32. This means -1 is the same thing as 2^32 - 1 or 0xFFFFFFFF. This turns out to be really simple to use at a hardware level.
Combine four 8-bit unsigned ints into one 32-bit unsigned int
Shift each element by 24 - (index * 8), then OR them all together:
rgba = [255, 255, 255, 255]
rgba[0] << 24 | rgba[1] << 16 | rgba[2] << 8 | rgba[3]
I didn't shift rgba[3]
because shifting by zero has no effect.
Some measurements:
Using unpack
Benchmark.measure do
100_000.times do
rgba = [255, 255, 255, 255]
rgba.pack('C*').unpack('L')[0]
end
end
Result:
=> #<Benchmark::Tms:0x007fe137005350
@cstime=0.0,
@cutime=0.0,
@label="",
@real=0.146899,
@stime=0.0,
@total=0.1399999999999999,
@utime=0.1399999999999999>
Using bitwise operators
Benchmark.measure do
100_100.times do
rgba = [255, 255, 255, 255]
rgba[0] << 24 | rgba[1] << 16 | rgba[2] << 8 | rgba[3]
end
end
Result:
=> #<Benchmark::Tms:0x007fd66438fd28
@cstime=0.0,
@cutime=0.0,
@label="",
@real=0.088995,
@stime=0.0,
@total=0.08000000000000007,
@utime=0.08000000000000007>
Convert Integer in Hex String Notation into a signed 8-Bit Integer
The c
directive comes very close but it expects a different input: a single character representing the signed 8-bit integer. This requires the input "0xff"
to be "\xff"
. So this conversion must take place first. At least one method known by you can be used here; the other one is Integer#chr
:
"0xff".hex.chr # => "\xFF"
And the complete solution:
"0xff".hex.chr.unpack1(?c) # => -1
Using ruby to convert unsigned integers stored as signed back to the original value
I'm not sure of Ruby specifics, but essentially you need to add 2^64 if the number is negative. That's assuming the number is stored as 2's complement, which it almost certainly is.
FYI, the 2's complement system, essentially it treats a (say) 32-bit number as a number mod 2^32. This means -1 is the same thing as 2^32 - 1 or 0xFFFFFFFF. This turns out to be really simple to use at a hardware level.
Reading a binary 16-bit signed (big-endian) integer in Ruby
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]
Related Topics
How to Give a Sub-Module the Same Name as a Top-Level Class
Command for Displaying a Gem's Dependencies
How Do Version Numbers Work for Mri Ruby
How to Count Existing Instances of a Class in Ruby
Rmagick - How to Find Out the Pixel Dimension of an Image
Installing Ruby-2.1.2: Cannot Load Such File -- Openssl (Loaderror)
Ruby: Array Contained in Array, Any Order
How to Correctly Install Rvm in Docker
Problem Using Openstruct with Erb
How to Specify the Location of the Chromedriver Binary
Rails: Methods Shared by Multiple Controllers
How to Split a String by Commas Except Inside Parenthesis, Using a Regular Expression
How to Model a Mutual Friendship in Rails
How to Use Views and Layouts with Ruby and Erb (Not Rails)
How to Get Out of a "Hung" State in Irb