in reply to converting binary to decimal

A little simpler, and slightly faster :)

#!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11165274 use warnings; print binary2decimal( 1 . 0 x 8192 ), "\n"; sub binary2decimal { my $n = 0; $n = (0 . $n =~ tr/1-9/246802468/r | $n =~ tr/1-9/00001/r . $_) =~ s/^0+(?=.)//r for split //, shift; return $n; }

Outputs:

1090748135619415929462984244733782862448264161996232692431832786189721 +331849119295216264234525201987223957291796157025273109870820177184063 +610979765077554799078906298842192989538609825228048205159696851613591 +638196771886542609324560121290553901886301017900252535799917200010079 +600026535836800905297805880952350501630195475653911005312364560014847 +426035293551245843928918752768696279344088055617515694349945406677825 +140814900616105920256438504578013326493565836047242407382442812245131 +517757519164899226365743722432277368075027627883045206501792761700945 +699168497257879683851737049996900961120515655050115561271491492515342 +105748966629547032786321505730828430221664970324396138635251626409516 +168005427623435996308921691446181187406395310665404885739434832877428 +167407495370993511868756359970390117021823616749458620969857006263612 +082706715408157066575137281027022310927564910276759160520878304632411 +049364568754920967322982459184763427383790272448438018526977764941072 +715611580434690827459339991961414242741410599117426060556483763756314 +527611362658628383368621157993638020878537675545336789915694234433955 +666315070087213535470255670312004130725495834508357439653828936077080 +978550578912967907352780054935621561090795845172954115972927479877527 +738560008204118558930004777748727761853813510493840581861598652211605 +960308356405941821189714037868726219481498727603653616298856174822413 +033485438785324024751419417183012281078209729303537372804574372095228 +703622776363945290869806258422355148507571039619387449629866808188769 +662815778153079393179093143648340761738581819563002994422790754955061 +288818308430079648693232179158765918035565216157115402992120276155607 +873107937477466841528362987708699450152031231862594203085693838944657 +061346236704234026821102958954951197087076546186622796294536451620756 +509351018906023773821539532776208676978589731966330308893304665169436 +185078350641568336944530051437491311298834367265238595404904273455928 +723949525227184617404367854754610474377019768025576605881038077270707 +717942221977090385438585844095492116099852538903974655703943973086090 +930596963360767529964938414598185705963754561497355827813623833288906 +309004288017321424808663962671333528009232758350873059614118723781422 +101460198615747386855096896089189180441339558524822867541113212638793 +675567650340362970031930023397828465318547238244232028015189689660418 +822976000815437610652254270163595650875433851147123214227266605403581 +781469090806576468950587661997186505665475715792896

Replies are listed 'Best First'.
Re^2: converting binary to decimal
by Anonymous Monk on Jun 06, 2025 at 14:46 UTC
    What!? :-O O.o

    How does this work? For example, you pass an argument, but in your sub you do not refer to $_[0] not even once. I don't understand this.

      It's consecutive doubling and adding from left to right
      • the first tr doubles every digit mod 10 1->2, ... 5->0, 6->2,...
      • the second tr adds a carry bit for every 5-9 -> 1
      • since the next bit is appended, the carry bit is shifted to the left
      • the | does a bitwise or which adds the bits ²
      for example if $n == "08" and the next bit is "1", you'll get "06" | "11" == "17" and so on.

      tybalt loves constructing¹ regex-automatons on strings

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

      ¹) cryptic

      ²) this part is a bit (sic ;) voodoo for me

        Hmm... That's amazing. But i tried to break it down into more easily understandable parts for me, and I think I broke it! Can you please show me why it no longer works? EDIT: I think I know what I did wrong. I accidentally doubled the "|" character. I can't even type. X_X

        sub binary2decimal { defined $_[0] or return 0; my $B = $_[0]; $B =~ tr|01||cd; # Remove illegal chars $B =~ s/^0+//; # Remove preceding zeros my @BITS = split(//, $B); my $n = 0; my $copy1; my $copy2; my $copy3; foreach (@BITS) { $copy1 = $n; $copy2 = $n; $copy1 =~ tr/1-9/246802468/; $copy2 =~ tr/1-9/00001/; $n = (0 . $copy1 || $copy2 . $_); # This should be | not || $n =~ s/^0+(?=.)//; } return $n; }

      shift in a sub shifts @_, the array that holds the sub's arguments.

        Oh oh, I see!! So, you get the value of $_[0] using shift, then you split the incoming string into individual characters, then you iterate through each character one by one performing this Chinese transform on each digit:
        
        $n = (0 . $n =~ tr/1-9/246802468/r | $n =~ tr/1-9/00001/r . $_) =~
            s/^0+(?=.)//r

        I have no idea what I'm looking at, but I think, if I can ever come up with code like this, I will have become a Perl hacker. Haha for example, I don't understand how transforming digits from 1-9 into 246802468 is going to end up as a decimal in the end. So, I don't understand any of this. But I find it fascinating/amazing.

        I'm Harangzsolt33, but somehow I got logged out.