Easiest way to determine sizeof( double ) and sizeof( int ) from Ruby?
For unpacking complex binary strings with mixed doubles and integers using Ruby's String.unpack I need to determine offsets within the binary string. Commonly, doubles are 8 bytes and integers are 4 bytes, but in order to make my code machine-independent, I would like to query these sizes from within my Ruby code.
What is the easiest开发者_StackOverflow社区 way to determine the size of integers and doubles from within Ruby, i.e., request the response of a request to C's sizeof( type )
method?
I have found a workable solution, by using Array#pack
, the inverse method of String#unpack
. By packing a string of 1 integer or 1 double it is possible to determine the size of integers and doubles from within ruby itself which gives the same results as using sizeof(int)
or sizeof(double)
(because of the implementation of Array#pack
in C):
[1.to_i].pack("i").size # 4
[1.to_f].pack("d").size # 8
This is so obvious that i am probably missing the point:
puts 1.size #=> 4
puts (256**10 - 1).size #=> 12
I'm not familiar with the Ruby language or its build/distribution system. However, the existence of Rake suggests that it's possible to create custom files on package installation - for example a configuration file which exports the result of the following commands as Ruby constants:
echo __SIZEOF_INT__ | gcc -E -P -
echo __SIZEOF_DOUBLE__ | gcc -E -P -
My current solution is to have a small C program, sizeofdouble.c
:
#include <stdio.h>
int main() {
printf( "%lu", sizeof(double) );
}
which, when compiled to a sizeofdouble
executable can be called from ruby with
sizeofdouble = `./sizeofdouble`.to_i
but that's an ugly hack, rather than a clean solution to this problem.
I know I'm late to the party here, but ruby's Fiddle
library exposes the sizes of all the data types you might want as constants. Here are the results on my system (64-bit MacOS 10.13):
require 'fiddle'
Fiddle::SIZEOF_SHORT # => 2
Fiddle::SIZEOF_INT # => 4
Fiddle::SIZEOF_DOUBLE # => 8
Fiddle::SIZEOF_SIZE_T # => 8
Fiddle::SIZEOF_SSIZE_T # => 8
See the ruby docs here
精彩评论