Variable size/Set

From Rosetta Code
Revision as of 13:37, 5 August 2010 by 132.199.97.100 (talk) (omit from Unlambda)
Task
Variable size/Set
You are encouraged to solve this task according to the task description, using any language you may know.

Demonstrate how to specify the minimum size of a variable or a data type.

Ada

<lang ada>type Response is (Yes, No); -- Definition of an enumeration type with two values for Response'Size use 1; -- Setting the size of Response to 1 bit, rather than the default single byte size</lang>

AutoHotkey

The documentation explains how the built-in function VarSetCapacity() may be used to do so.

C

<lang c>#include <stdint.h>

int_least32_t foo;</lang>

Here foo is a signed integer with at least 32 bits. stdint.h also defines minimum-width types for at least 8, 16, 32, and 64 bits, as well as unsigned integer types.

C++

<lang Cpp>#include <boost/cstdint.hpp>

boost::int_least32_t foo;</lang>

C++03 does not specify a standard stdint.h or cstdint header. At least one widely used compiler (MSVC) does not support C99 and hence does not ship with stdint.h. The Boost C++ Libraries provide a portable implementation which should be used instead.

D

In D, any variables of static array of zero length has a size of zero. But such data is useless, as no base type element can be accessed. <lang d>typedef long[0] zeroLength ; writefln(zeroLength.sizeof) ; // print 0</lang> NOTE: a dynamic array variable's size is always 8 bytes, 4(32-bit) for length and 4 for a reference pointer of the actual storage somewhere in runtime memory.
The proper candidates of minimum size variable are empty structure, 1-byte size data type variable (include byte, ubyte, char and bool), and void, they all occupy 1 byte. <lang d>byte b ; ubyte ub ; char c ; bool t ;</lang> bool is logically 1-bit size, but it actually occupy 1 byte.
void can't be declared alone, but void.sizeof gives 1.
An empty structure is logically zero size, but still occupy 1 byte. <lang d>struct Empty { } writefln(Empty.sizeof) ; // print 1</lang>

J

<lang J>v=: </lang>

Here, v is specified to have a minimum size. In this case, the minimum size of the content is zero, though the size of the representation is somewhat larger.

Modula-3

<lang modula3>TYPE UByte = BITS 8 FOR [0..255];</lang> Note that this only works for records, arrays, and objects. Also note that the size in bits must be large enough to hold the entire range (in this case, 8 bits is the correct amount for the range 0 to 255) or the compiler will error.

Perl

I suppose you could use vec() or similar to twiddle a single bit. The thing is, as soon as you store this in a variable, the SV (the underlying C implementation of the most simple data type) already takes a couple dozen of bytes.

In Perl, memory is readily and happily traded for expressiveness and ease of use.

PL/I

<lang PL/I> declare i fixed binary (7), /* occupies one byte */

       j fixed binary (15), /* occupies two bytes */
       k fixed binary (31), /* occupies 4 bytes   */
       l fixed binary (63); /* occupies 8 bytes   */

declare d fixed decimal (1), /* occupies 1 byte */

       e fixed decimal (3), /* occupies 2 bytes   */
                            /* an so on ...       */
       f fixed decimal (15); /* occupies 8 bytes. */

declare b(16) bit (1) unaligned; /* occupies 2 bytes */ declare c(16) bit (1) aligned; /* occupies 16 bytes */

declare x float, /* occupies 4 bytes. */

       y float (15),         /* occupies 8 bytes. */
       z float (18);         /* occupies 10 bytes */

</lang>

PicoLisp

In PicoLisp, all variables have the same size (a single cell). But it is possible to create a data structure of a given minimal size with the 'need' function.

Python

For compatibility with the calling conventions of external C functions, the ctypes module has functions that map data types and sizes between Python and C:

ctypes type C type Python type
c_char char 1-character string
c_wchar wchar_t 1-character unicode string
c_byte char int/long
c_ubyte unsigned char int/long
c_short short int/long
c_ushort unsigned short int/long
c_int int int/long
c_uint unsigned int int/long
c_long long int/long
c_ulong unsigned long int/long
c_longlong __int64 or long long int/long
c_ulonglong unsigned __int64 or unsigned long long int/long
c_float float float
c_double double float
c_longdouble long double float
c_char_p char * (NUL terminated) string or None
c_wchar_p wchar_t * (NUL terminated) unicode or None
c_void_p void * int/long or None

Tcl

In Tcl, most values are (Unicode) strings. Their size is measured in characters, and the minimum size of a string is of course 0. However, one can arrange, via write traces, that the value of a variable is reformatted to bigger size. Examples, from an interactive tclsh session: <lang Tcl>% proc format_trace {fmt _var el op} {upvar 1 $_var v; set v [format $fmt $v]}

% trace var foo w {format_trace %10s} % puts "/[set foo bar]/" / bar/

% trace var grill w {format_trace %-10s} % puts "/[set grill bar]/" /bar /</lang> ..or limit its size to a certain length: <lang Tcl>% proc range_trace {n _var el op} {upvar 1 $_var v; set v [string range $v 0 [incr n -1]]}

% trace var baz w {range_trace 2} % set baz Frankfurt Fr</lang>

Ursala

There is no way to set the minimum size of natural, integer, or rational numbers, but no need because they all have unlimited precision.

For (mpfr format) arbitrary precision floating point numbers, there are several mechanisms for setting the minimum precision, although not the exact amount of real memory used.

  • If it's initialized from a literal constant, the compiler infers the intended precision from the number of digits in the constant (or 160 bits, whichever is greater).
  • The library function mpfr..grow(x,n) returns a copy of x with its precision increased by n bits (padded with zeros).
  • The library function mpfr..shrink(x,n) returns a copy of x with its precision reduced by n bits, or to MPFR_PREC_MIN, whichever is greater.
  • Library functions such as mpfr..pi and mpfr..const_catalan take a natural number specifying the precision as an argument and return a constant with at least that precision.
  • If two numbers of unequal precision are combined using any binary operation from the mpfr library, the result is computed and allocated using the greater precision of the two.

The last feature eliminates the need for explicitly setting the precision of numbers having exact representations, albeit contrary to the convention in physical sciences. <lang Ursala>p = mpfr..pi 200 # 200 bits of precision

x = mpfr..grow(1.0E+0,1000) # 160 default precision, grown to 1160

y = mpfr..shrink(1.0+0,40) # 160 default shrunk to 120

z = mpfr..add(p,y) # inherits 200 bits of precision

a = # 180 bits (not the default 160) because of more digits in the constant

1.00000000000000000000000000000000000000000000000000000E0</lang>