Easiest way to determine sizeof( double ) and sizeof( int ) from Ruby?
Asked Answered
R

5

1

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 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?

Rexanna answered 21/2, 2011 at 14:39 Comment(3)
where does the data come from? is the Ruby script necessarily run on the architecture which produces the values?Subdivision
Are you sure this is what you want to do? As @Cristoph indicates, the size is dependent on the program and platform that produced the binary strings, not the ruby program and platform consuming them. Any binary interface specification should have the layout explicitly specified somewhere (item size, endianness, padding, etc)Psephology
Yes, the question is under the assumption that the binary string was generated on the same machine as the recipient Ruby script.Rexanna
R
3

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
Rexanna answered 23/2, 2011 at 16:16 Comment(0)
H
2

This is so obvious that i am probably missing the point:

puts 1.size #=> 4
puts (256**10 - 1).size   #=> 12
Heaney answered 21/2, 2011 at 21:3 Comment(2)
Heh? The size of an int (making sure with puts 1.to_i.size) results in 8 on my machine (MBP, ruby 1.8,7), not 4, which is sizeof( int ) in C.Rexanna
I'm guessing you have a 64 bit processor, mine is 32 bit. I have no idea how C handles this.Heaney
S
1

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 -
Subdivision answered 21/2, 2011 at 17:35 Comment(2)
I can't get this to output anything else but the literal/original __SIZEOF_INT__ or __SIZEOF_DOUBLE__ strings (using gcc 4.2.1 on a mac or gcc 4.1.2 on a linux box, with or without -c).Rexanna
according to my google-fu, the patch dates from 2007; no idea when it was first included in a release, but I can confirm that it's in 4.3.4...Subdivision
R
0

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.

Rexanna answered 21/2, 2011 at 14:56 Comment(1)
your C program is not portable, as sizeof (long) == sizeof (size_t) is not necessarily true; either use the z length modifier (which is not universally supported) or cast to unsigned (no need for unsigned long)Subdivision
D
0

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

Doley answered 18/4, 2019 at 17:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.