Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: bit shifts

From: joel:neely:fedex at: 20-Sep-2001 3:04

Hi, Hallvard, Hallvard Ystad wrote:
> Gregg Irwin skrev (Tuesday 11.09.2001, kl. 23.31): > > If you're working with numeric values you can multiply or > > divide, by powers of two. > > For example (please correct any misinformation REBOLers!): > > > > shl: to-integer (value * (2 ** shift-count)) > > shr: to-integer (value / (2 ** shift-count)) > > Well, this mostly works, but wheras the integer value 1 > right-shifted becomes 0, the same value divided by 2 becomes > 0,5. Even if one should round the value (how do we do so in > rebol, by the way?), it would become 1, not 0. So I think > it's better to shift "à proprement dire". >
Right-shifting the value 1 by one digit produces the value 0.1 (one-half, if we're dealing with binary) which becomes 0 once TO-INTEGER deletes the fractional part. (TO-INTEGER truncates; it doesn't round, as shown by
>> to-integer 0.9999999
== 0 and similar exercises...) The same thing applies to right-shifting by a larger number of digits -- e.g. 27 right-shifted by 3 digits (in binary) 11011 -> 11.011 -> 11 and
>> to-integer 27 / (2 ** 3)
== 3 The nice thing about this formula is that the base is just another parameter, which could be changed to any other value one wishes. For example, using base 3, one can right-shift 25 by two "trits" (ternary digits) via
>> to-integer 25 / (3 ** 2)
== 2 with the details as before (in ternary, of course ;-) twentyfive -> 221 -> 2.21 -> 2 As for your other question,
> ... Even if one should round the value (how do we do so in > rebol, by the way?)...
one can round by adding the bias prior to applying TO-INTEGER as in round-to-int: func [x [decimal!]] [to-integer x + 0.5]
>> round-to-int 1.4 == 1 >> round-to-int 1.5 == 2 >> round-to-int 1.6 == 2
or to a specified number of (fractional) decimal digits by round-decimal: func [ x [decimal!] ndigs [integer!] /local factor ][ factor: 10 ** ndigs (to-integer x * factor + 0.5) / factor ]
>> round-decimal 1.23456 1 == 1.2 >> round-decimal 1.23456 2 == 1.23 >> round-decimal 1.23456 3 == 1.235 >> round-decimal 1.23456 4 == 1.2346
A negative number of digits actually rounds away the non- fractional digits, as well:
>> round-decimal 1234.5678 1 == 1234.6 >> round-decimal 1234.5678 0 == 1235 >> round-decimal 1234.5678 -1 == 1230 >> round-decimal 1234.5678 -2 == 1200
HTH! -jn- -- ------------------------------------------------------------ Programming languages: compact, powerful, simple ... Pick any two! joel'dot'neely'at'fedex'dot'com