Variable size/Get: Difference between revisions

From Rosetta Code
Content added Content deleted
(Modula-3)
Line 98: Line 98:
some_function =: +/ % #
some_function =: +/ % #
7!:5<'some_function'
7!:5<'some_function'

=={{header|Modula-3}}==
BITSIZE and BYTESIZE are built in functions.

<pre>
MODULE Size EXPORTS Main;

FROM IO IMPORT Put;
FROM Fmt IMPORT Int;

BEGIN
Put("Integer in bits: " & Int(BITSIZE(INTEGER)) & "\n");
Put("Integer in bytes: " & Int(BYTESIZE(INTEGER)) & "\n");
END Size.
</pre>

Output:
<pre>
Integer in bits: 32
Integer in bytes: 4
</pre>


=={{header|OCaml}}==
=={{header|OCaml}}==

Revision as of 03:12, 31 December 2008

Task
Variable size/Get
You are encouraged to solve this task according to the task description, using any language you may know.

Demonstrate how to get the size of a variable.

Ada

Ada represents the size of a variable in bits, not bytes like many other languages.

Int_Bits : constant Integer := Integer'size;
Whole_Bytes : constant Integer := Int_Bits / Storage_Unit; -- Storage_Unit is the number of bits per storage element

C

printf("An int contains %d bytes.\n", sizeof(int));

C++

Store the size of an int in bytes:

#include <cstdlib>
std::size_t intsize = sizeof(int);

Note: sizeof can be used without the header <cstdlib>; the latter is only needed for the type std::size_t, which is an alias for whatever type is used to store sizes for the given compiler.

Output the number of bits of an int:

#include <climits>
#include <cstdlib>
std::size_t intbits = CHAR_BITS*sizeof(int);

Note: the type char is always 1 byte (which, however, need not be 8 bits).

Get the size of a variable in bytes:

#include <cstdlib>
int a = 1;
std::size_t a_size = sizeof a;

Note: Parentheses are needed around types, but not around variables.

Get the size of an expression's type:

#include <cstdlib>
std::size_t size = sizeof (3*6 + 7.5);

D

Every type and variable in D has a property sizeof, which give the size of the type in bytes. eg.

int i ;
writefln(i.sizeof) ;        // print 4 
int[13] ints1 ;             // static integer array of length 13
writefln(ints1.sizeof) ;    // print 52
int[] ints2 = new int[13] ; // dynamic integer array, variable length, currently 13
writefln(ints2.sizeof) ;    // print 8, all dynamic array has this size
writefln(ints2.length) ;    // print 13, length is the number of allocated element in aggregated type

Delphi

i := sizeof([any variable or structure]);

Fortran

Works with: Fortran version 90 and later

The intrinsic functions bit_size and digits can be used to find the size of an integer. Bit_size returns the number of bits in an integer while digits returns the number of significant digits in the integer. Because of the use of signed intergers this will be one less than the bit size. Digits can be used on real variables where it returns the number of significant figures in the mantissa.

INTEGER, PARAMETER ::  i8 = SELECTED_INT_KIND(2)
INTEGER, PARAMETER :: i16 = SELECTED_INT_KIND(4)
INTEGER, PARAMETER :: i32 = SELECTED_INT_KIND(8)
INTEGER, PARAMETER :: i64 = SELECTED_INT_KIND(16)
INTEGER(i8)  :: onebyte = 0
INTEGER(i16) :: twobytes = 0
INTEGER(i32) :: fourbytes = 0
INTEGER(i64) :: eightbytes = 0

WRITE (*,*) BIT_SIZE(onebyte), DIGITS(onebyte)             ! prints 8 and 7
WRITE (*,*) BIT_SIZE(twobytes), DIGITS(twobytes)           ! prints 16 and 15
WRITE (*,*) BIT_SIZE(fourbytes),  DIGITS(fourbytes)        ! prints 32 and 31
WRITE (*,*) BIT_SIZE(eightbytes),  DIGITS(eightbytes)      ! prints 64 and 63
WRITE (*,*) DIGITS(0.0), DIGITS(0d0)                       ! prints 24 and 53

Haskell

only works with types that instance Storable:

import Foreign

sizeOf (undefined :: Int) -- size of Int in bytes (4 on mine)
sizeOf (undefined :: Double) -- size of Double in bytes (8 on mine)
sizeOf (undefined :: Bool) -- size of Bool in bytes (4 on mine)
sizeOf (undefined :: Ptr a) -- size of Ptr in bytes (4 on mine)

IDL

IDL is array based, so its size() function is geared towards that:

arr = intarr(3,4)
print,size(arr)
;=> prints this:
       2           3           4           2          12

The result means: 2 dimensions in the array, the first dimension has extent 3, the second has extent 4, the elements of the array are 2-byte integers (IDL's default for an "int"), there's a total of 12 elements in the array.

J

In J, the function 7!:5 is analogous to sizeof in C. For example:

   some_variable =: 42
   7!:5<'some_variable'

An advantage of 7!:5 is that it can be used on any name, including functions, operators, etc (i.e. it's not just restricted to variables):

   some_function =: +/ % #
   7!:5<'some_function'

Modula-3

BITSIZE and BYTESIZE are built in functions.

MODULE Size EXPORTS Main;

FROM IO IMPORT Put;
FROM Fmt IMPORT Int;

BEGIN
  Put("Integer in bits: " & Int(BITSIZE(INTEGER)) & "\n");
  Put("Integer in bytes: " & Int(BYTESIZE(INTEGER)) & "\n");
END Size.

Output:

Integer in bits: 32
Integer in bytes: 4

OCaml

<ocaml>(** The result is the size given in word.

 The word size in octet can be found with (Sys.word_size / 8).
 (The size of all the datas in OCaml is at least one word, even chars and bools.)
  • )

let sizeof v =

 let counted_yet d r =
   List.exists (fun v -> v == r) d
 in
 let rec rec_size d r =
   if counted_yet d r then (1, d) else
   if not(Obj.is_block r) then (1, r::d) else
   if (Obj.tag r) = (Obj.double_tag) then (2, r::d) else
   if (Obj.tag r) = (Obj.string_tag) then (Obj.size r, r::d) else
   if (Obj.tag r) = (Obj.object_tag) ||
      (Obj.tag r) = (Obj.closure_tag)
   then invalid_arg "please only provide datas"
   else
     let len = Obj.size r in
     let rec aux d sum i =
       if i >= len then (sum, r::d) else
       let this = Obj.field r i in
       let this_size, d = rec_size d this in
       aux d (sum + this_size) (i+1)
     in
     aux d (1) 0
 in
 fst(rec_size [] (Obj.repr v))
</ocaml>

testing in the toplevel: <ocaml>

  1. sizeof 234 ;;

- : int = 1

  1. sizeof 23.4 ;;

- : int = 2

  1. sizeof (1,2);;

- : int = 3

  1. sizeof (2, 3.4) ;;

- : int = 4

  1. sizeof (1,2,3,4,5) ;;

- : int = 6

  1. sizeof [| 1;2;3;4;5 |] ;;

- : int = 6

  1. sizeof [1;2;3;4;5] ;;

- : int = 11

(* because a list is equivalent to *)

  1. sizeof (1,(2,(3,(4,(5,0))))) ;;

- : int = 11

  1. type foo = A | B of int | C of int * int ;;

type foo = A | B of int | C of int * int

  1. sizeof A ;;

- : int = 1

  1. sizeof (B 3) ;;

- : int = 2

  1. sizeof (C(1,2)) ;;

- : int = 3

  1. sizeof true ;;

- : int = 1

  1. sizeof 'A' ;;

- : int = 1

  1. sizeof `some_pvar ;;

- : int = 1

  1. sizeof "" ;;

- : int = 1

  1. sizeof "Hello!" ;;

- : int = 2 (* remember the size is given in words

  (so 4 octets on 32 bits machines) *)
  1. for i=0 to 16 do
   Printf.printf "%d -> %d\n" i (sizeof(String.create i))
 done;;

0 -> 1 1 -> 1 2 -> 1 3 -> 1 4 -> 2 5 -> 2 6 -> 2 7 -> 2 8 -> 3 9 -> 3 10 -> 3 11 -> 3 12 -> 4 13 -> 4 14 -> 4 15 -> 4 16 -> 5 - : unit = ()

  1. sizeof(Array.create 10 0) ;;

- : int = 11

  1. sizeof(Array.create 10 (String.create 20)) ;;

- : int = 16

  1. sizeof(Array.init 10 (fun _ -> String.create 20)) ;;

- : int = 61 </ocaml>

Perl

Works with: Perl version 5.x

<perl>

use Devel::Size;

my $var = 9384752;
my @arr = (1, 2, 3, 4, 5, 6);
print size($var);
print total_size(@arr);

</perl>

Pop11

From abstract point of view Pop11 variables are bindings between identifiers and values. In concrete terms Pop11 variables store references to values in the heap. Each reference takes one machine word (4 bytes on 32-bit machines and 8 bytes on 64-bit machines). Pop11 identifiers take 3 machine words, but are only needed for "permanent" variables (lexical variables do not need identifiers after compilation). Additionally variable names (words) need space (4 machine for word + space for string corresponding to the word). The bottom line is: variable needs one machine word plus some overhead due to introspection.

Form user point of view more important is space taken by values (size of values referenced by a single variable typically varies during program execution). The datasize function gives amount (in machine words) of space directly used by given value:

;;; Prints 0 because small integers need no heap storage
datasize(12) =>
;;; Prints 3: 3 character fits into single machine word, 1 word
;;; for tag, 1 for length
datasize('str') =>
;;; 3 element vector takes 5 words: 3 for values, 1 for tag, 1 for
;;; length
datasize({1 2 3}) =>
;;; Prints 3 because only first node counts
datasize([1 2 3]) =>

Note that large amount of data my be referenced from given value, but this data is potentially shared, so there is no canonical way to assign it to a single value or variable.

Tcl

Since all variables are ultimately strings in Tcl, this is easy:

string bytelength $var

Toka

There are two primary data types in Toka, cells and characters. The size of these can be obtained easily:

 char-size .
 cell-size .

If you load the floating point support, you can also obtain the size of a floating point number:

 needs floats
 float-size .

All sizes are returned in bytes.