Thanks
Harry
Harry Irwing schrieb:
> I want to convert a binary string (e.g. 0101) to decimal.
% scan 0101 %i v
1
% puts $v
65
Peter
Harry Irwing schrieb:
> But binary 0101 is decimal 9 not 65!
Ups, sorry. (65 realy looked a bit high for such a short bin string)
I've looked in the man pages, only conversion from hex or oct
seems to be possible
Peter
Rolf.
--
---------------------------------------------------------------
Rolf Schroedter
German Aerospace Center
Institute of Space Sensor Technology and Planetary Exploration
D-12489 Berlin, Rutherfordstrasse 2
Tel/Fax: (+49) (30) 67055-416/384
Email: Rolf.Sc...@dlr.de
set bin 010100101
set dec 0
foreach char [split $bin ""] {set dec [expr {($dec << 1) + $char}]}
Need to check for characters in $bin not 0 or 1.
--
Glenn
proc bin_decode { bitstream } {
binary scan [binary format B* [format %032s $bitstream]] I value
return $value
}
% bin_decode 0101
5
% bin_decode 111011
59
Hope this helps.
Jeff David
jld...@lucent.com
> foreach char [split $bin ""]
Very nice! never thought of that before
Tom Wilkason
> But binary 0101 is decimal 9 not 65!
9? I can get 5 or 10, but not 9.
--
Jonathan E. Guyer
And if you expect the digits in the other order:
proc bin_decode_LE {bitstream} {
regsub -all { } [format %-32s $bitstream] 0 binstring
binary scan [binary format b* $binstring] i value
return $value
}
% bin_decode_LE 0101
10
% bin_decode_LE 111011
55
Donal.
--
Donal K. Fellows http://www.cs.man.ac.uk/~fellowsd/ fell...@cs.man.ac.uk
-- [Perl] is mostly pretty "intuitive" in a certain way.
-- Jason Williams <ja...@compsoc.man.ac.uk>
Here's a procedure that does what you want:
proc bindec {binum} {
# =======================================================
# Converts an binary number into the decimal equivalent.
# Binary must be integer and positive.
# Binary number is a string of binary digits (0 or 1).
# =======================================================
# create an empty container to hold the answer
set decnum 0
# find number of digits of binary number and set length
set length [string length $binum]
# since string starts at position 0 adjust length
set length [expr $length - 1]
# loop to process all bits
for {set i 0} {$i < [expr $length + 1]} {incr i} {
# point to the digit to be processed
set pointeur [expr $length - $i]
# find the weight i.e. decimal value of that position
# Nth bit from end has a value of 2^(N-1)
set weight [expr pow(2,$i)]
# get the bit value of the bit being processed
set selectbit [string index $binum $pointeur]
# multiply bit value by position weight to get
# contribution of that particular bit to decimal number
set digitvalue [expr $selectbit * $weight]
# Accumulat into decnum the contribution of the bit
set decnum [expr $decnum + $digitvalue]
}
# return from the procedure with the result
return $decnum}
#
# ==========================================================
# Examples of use
# set a [bindec 10011] : $a becomes 19
# set b 10101011 ; set a [bindec $b] : $a becomes 171
#
# Apr 24 2001 - V. Georgiou
# ===========================================================
Or try this one, which should be quite faster :
proc bin2int {value} {
binary scan [binary format b32 $value] i result
return [expr {$result & 0xffffffff}]
}
Eric.
-----
Eric Hassold
Evolane, 87 avenue de Nice, F-06800 Cagnes-sur-Mer
Tel. : (+33) 4.931.932.98 Fax : (+33) 4.931.932.94
http://www.evolane.fr
CSLUsh 2.0b2% bin2int 100000000
1
CSLUsh 2.0b2% bin2int 101
5
CSLUsh 2.0b2% bin2int 100
1
CSLUsh 2.0b2% bin2int 10000001
129
CSLUsh 2.0b2%
Can your solution be modified to take care of this while remaing
compact?
(you can always append an 1 at the end of the number and then subtract
one from the decimal and divide the result by two to get your answer)
I am not very familar with Tcl yet to understand what you do, nor
do you explain it in comments (remember the 70/30 rule of programming,
a program should be 70 percent comments and 30 percent code).
I presume this is not the answer you were after?
> Can your solution be modified to take care of this while remaing
> compact?
Well, my solution is pretty short and simple:
proc bin2int {bin} {
binary scan [binary format B32 [format %032d $bin]] I int
return $int
}
Doesn't work for larger quantities on 64-bit platforms due to use of I
specifier to [binary scan] which is defined to be 32-bit only...
Donal.
--
Donal K. Fellows http://www.cs.man.ac.uk/~fellowsd/ fell...@cs.man.ac.uk
-- Always running as a superuser is not a fault, it's an OS preference.
-- <mz...@hotmail.com>
Right, forgotten to format the input so that it is exactly 32 bits/bytes
long
"Donal K. Fellows" <fell...@cs.man.ac.uk> wrote :
> Well, my solution is pretty short and simple:
>
> proc bin2int {bin} {
> binary scan [binary format B32 [format %032d $bin]] I int
> return $int
> }
>
Right, this is the correct way. However, this doesn' work as is, since the
format statement will consider $bin as an integer (whereas it is in fact a
string for now), and this integer value may be too large (whereas it is a
valid binary number) :
bin2int 111111111111111 => error : integer value too large to represent
So, the same code, but formatting it as a string :
proc bin2int {bin} {
binary scan [binary format B32 [format %032s $bin]] I int
return $int
}
bin2int 111111111111111 => 32767
> I am not very familar with Tcl yet to understand what you do, nor
> do you explain it in comments (remember the 70/30 rule of programming,
> a program should be 70 percent comments and 30 percent code).
Sounds exact in general....but my (fast) answer was not supposed to be "a
program", but more something like a hint to help you go in the right
direction (something that should have been read as "take a look at the
'binary' manpage" :-).
Best regards.
IIRC not all sprintf()s (on which [format] is based) support the 0
modifier on %s. Or am I getting mixed up? :^(