Understand “ibase” and “obase” in case of conversions with bc?bc: Why does `ibase=16; obase=10; FF`...

How to avoid typing 'git' at the begining of every Git command

What differences exist between adamantine and adamantite in all editions of D&D?

Were tables of square roots ever in use?

empApi with Lightning Web Components?

Is using 'echo' to display attacker-controlled data on the terminal dangerous?

Why did the World Bank set the global poverty line at $1.90?

A word that means "blending into a community too much"

Teaching a class likely meant to inflate the GPA of student athletes

If there's something that implicates the president why is there then a national security issue? (John Dowd)

Live action TV show where High school Kids go into the virtual world and have to clear levels

Why was this person allowed to become Grand Maester?

Write a function that checks if a string starts with or contains something

Do people with slow metabolism tend to gain weight (fat) if they stop exercising?

How do free-speech protections in the United States apply in public to corporate misrepresentations?

How long is it safe to leave marker on a Chessex battle map?

Does the new finding on "reversing a quantum jump mid-flight" rule out any interpretations of QM?

2019 gold coins to share

Who voices the small round football sized demon in Good Omens?

Is it safe to change the harddrive power feature so that it never turns off?

Why Does Mama Coco Look Old After Going to the Other World?

Why do radiation hardened IC packages often have long leads?

Varying the size of dots in a plot according to information contained in list

Why we don’t make use of the t-distribution for constructing a confidence interval for a proportion?

How to safely destroy (a large quantity of) valid checks?



Understand “ibase” and “obase” in case of conversions with bc?


bc: Why does `ibase=16; obase=10; FF` returns FF and not 255?Calculate variable, and output it to another variablebash: -eq vs. == and `bc` output typeFloat operations with bc not precise?How do I get bc to start decimal fractions with a leading zeroStart bc with pi definedAppend to a pipe and pass on?divide two columns, not with each otherbash + arithmetic calculation with bashbash + divide number with round number to up or downbc: Why does `ibase=16; obase=10; FF` returns FF and not 255?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







22















I often use bc utility for converting hex to decimal and vice versa. However, it is always bit trial and error how ibase and obase should be configured. For example here I want to convert hex value C0 to decimal:



$ echo "ibase=F;obase=A;C0" | bc
180
$ echo "ibase=F;obase=10;C0" | bc
C0
$ echo "ibase=16;obase=A;C0" | bc
192


What is the logic here? obase(A in my third example) needs to be in the same base as the value which is converted(C0 in my examples) and ibase(16 in my third example) has to be in the base where I am converting to?










share|improve this question


















  • 1





    for hex calculations (input and output in hex) I have to set obase before ibase!

    – Paschalis
    Sep 15 '16 at 2:59




















22















I often use bc utility for converting hex to decimal and vice versa. However, it is always bit trial and error how ibase and obase should be configured. For example here I want to convert hex value C0 to decimal:



$ echo "ibase=F;obase=A;C0" | bc
180
$ echo "ibase=F;obase=10;C0" | bc
C0
$ echo "ibase=16;obase=A;C0" | bc
192


What is the logic here? obase(A in my third example) needs to be in the same base as the value which is converted(C0 in my examples) and ibase(16 in my third example) has to be in the base where I am converting to?










share|improve this question


















  • 1





    for hex calculations (input and output in hex) I have to set obase before ibase!

    – Paschalis
    Sep 15 '16 at 2:59
















22












22








22


4






I often use bc utility for converting hex to decimal and vice versa. However, it is always bit trial and error how ibase and obase should be configured. For example here I want to convert hex value C0 to decimal:



$ echo "ibase=F;obase=A;C0" | bc
180
$ echo "ibase=F;obase=10;C0" | bc
C0
$ echo "ibase=16;obase=A;C0" | bc
192


What is the logic here? obase(A in my third example) needs to be in the same base as the value which is converted(C0 in my examples) and ibase(16 in my third example) has to be in the base where I am converting to?










share|improve this question














I often use bc utility for converting hex to decimal and vice versa. However, it is always bit trial and error how ibase and obase should be configured. For example here I want to convert hex value C0 to decimal:



$ echo "ibase=F;obase=A;C0" | bc
180
$ echo "ibase=F;obase=10;C0" | bc
C0
$ echo "ibase=16;obase=A;C0" | bc
192


What is the logic here? obase(A in my third example) needs to be in the same base as the value which is converted(C0 in my examples) and ibase(16 in my third example) has to be in the base where I am converting to?







bc






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Apr 30 '15 at 12:48









MartinMartin

3752674146




3752674146








  • 1





    for hex calculations (input and output in hex) I have to set obase before ibase!

    – Paschalis
    Sep 15 '16 at 2:59
















  • 1





    for hex calculations (input and output in hex) I have to set obase before ibase!

    – Paschalis
    Sep 15 '16 at 2:59










1




1





for hex calculations (input and output in hex) I have to set obase before ibase!

– Paschalis
Sep 15 '16 at 2:59







for hex calculations (input and output in hex) I have to set obase before ibase!

– Paschalis
Sep 15 '16 at 2:59












4 Answers
4






active

oldest

votes


















34














What you actually want to say is:



$ echo "ibase=16; C0" | bc
192


for hex-to-decimal, and:



$ echo "obase=16; 192" | bc
C0


for decimal-to-hex.



You don't need to give both ibase and obase for any conversion involving decimal numbers, since these settings default to 10.



You do need to give both for conversions such as binary-to-hex. In that case, I find it easiest to make sense of things if you give obase first:



$ echo "obase=16; ibase=2; 11000000" | bc
C0


If you give ibase first instead, it changes the interpretation of the following obase setting, so that the command has to be:



$ echo "ibase=2; obase=10000; 11000000" | bc
C0


This is because in this order, the obase value is interpreted as a binary number, so you need to give 10000₂=16 to get output in hex. That's clumsy.





Now let’s work out why your three examples behave as they do.





  1. echo "ibase=F;obase=A;C0" | bc



    180



    That sets the input base to 15 and the output base to 10, since a single-digit value is interpreted in hex, according to POSIX. This asks bc to tell you what C0₁₅ is in base A₁₅=10, and it is correctly answering 180₁₀, though this is certainly not the question you meant to ask.




  2. echo "ibase=F;obase=10;C0" | bc



    C0



    This is a null conversion in base 15.



    Why? First, because the single F digit is interpreted in hex, as I pointed out in the previous example. But now that you've set it to base 15, the following output base setting is interpreted that way, and 10₁₅=15, so you have a null conversion from C0₁₅ to C0₁₅.



    That's right, the output isn't in hex as you were assuming, it's in base 15!



    You can prove this to yourself by trying to convert F0 instead of C0. Since there is no F digit in base 15, bc clamps it to E0, and gives E0 as the output.




  3. echo "ibase=16; obase=A; C0"



    192



    This is the only one of your three examples that likely has any practical use.



    It is changing the input base to hex first, so that you no longer need to dig into the POSIX spec to understand why A is interpreted as hex, 10 in this case. The only problem with it is that it is redundant to set the output base to A₁₆=10, since that's its default value.








share|improve this answer

































    7














    Setting ibase means you need to set obase in that same base. Explaining your examples will show this:



    echo "ibase=F;obase=A;C0" | bc


    You set bc to consider input numbers as represented in base 15 with the "ibase=F". "obase=A" sets output numbers to base 10, which is the default.



    bc reads C0 as a base 15 number: C = 12. 12*15 = 180.





    echo "ibase=F;obase=10;C0" | bc


    In this one, you set input to base 15, and output to 10 - in base 15, so output base is 15. C0 input in base 15 is C0 output in base 15.





    echo "ibase=16;obase=A;C0" | bc


    Set input to base 16, output to base 10 (A in base 16 is 10 in base 10).



    C0 converted to base 10 is: 12*16 = 192





    My personal rule is to set obase first, so that I can use base 10. Then set ibase, also using base 10.



    Note that bc does have an ironic exception: ibase=A and obase=A always sets input and output to base 10. From the bc man page:



    Single digit numbers always have the value of the digit 
    regardless of the value of ibase.


    This behavior is enshrined in the specification of bc: From the 2004 OpenGroup bc specification:



    When either ibase or obase is assigned a single digit value from 
    the list in 'Lexical Conventions in bc', the value shall be assumed
    in hexadecimal. (For example, ibase=A sets to base ten, regardless
    of the current ibase value.) Otherwise, the behavior is undefined
    when digits greater than or equal to the value of ibase appear in
    the input.


    That's why the ibase=F setting changed your input base to base 15, and why I recommended to always set the base using base 10. Avoid confusing yourself.






    share|improve this answer


























    • @StéphaneChazelas - I have a recollection of "ibase=A" working on a SysVr3 machine in 1989 or so. I bet it goes back farther that Single Unix Spec. I couldn't quickly google up an earlier ref.

      – Bruce Ediger
      Apr 30 '15 at 14:28











    • I think that's because there are more links around to the older specs since they have been around for longer. The same kind of things happen for apache/mysql/bugzilla... documentation where google gives you the doc for the older versions first instead of the latest.

      – Stéphane Chazelas
      Apr 30 '15 at 16:21



















    5














    All numbers are interpreted by GNU bc as the current input base that is in effect for the statement the number appears in. When you use a digit outside the current input interpret them as the highest digit available in the base (9 in decimal) when part of a multiple digit number, or as their normal values when used as a single digit number (A == 10 in decimal).



    From the GNU bc manual:




    Single digit numbers always have the value of the digit regardless of the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1. This makes the number FFF always be the largest 3 digit number of the input base.




    However, you should be aware that the POSIX standard only defines this behavior for assignments to ibase and obase, and not in any other context.



    From the SUS specification on bc:




    When either ibase or obase is assigned a single digit value from the list in Lexical Conventions in bc , the value shall be assumed in hexadecimal. (For example, ibase=A sets to base ten, regardless of the current ibase value.) Otherwise, the behavior is undefined when digits greater than or equal to the value of ibase appear in the input. Both ibase and obase shall have initial values of 10.




    The key factor you are missing is that F is not in fact sixteen, but is actually fifteen, so when you are setting ibase=F you are setting the input base to fifteen.



    Therefore, to portably set the ibase to hexadecimal from an unknown state, you therefore need to use two statements: ibase=A; ibase=16. However, in the beginning of the program you can rely on it being decimal and simply use ibase=16.






    share|improve this answer


























    • +1: Cute trick with ibase=A; ibase=16.

      – Warren Young
      Apr 30 '15 at 16:23











    • That's SUSv3, not SUSv6. SUSv4 is at pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

      – Stéphane Chazelas
      Apr 30 '15 at 16:25











    • I'd always thought the 6 and 7 in the headers were the version. I've never seen anything different - what are issue #1-5?

      – Random832
      Apr 30 '15 at 16:29











    • @Random832: SUS and POSIX aren't the same thing.

      – Warren Young
      Apr 30 '15 at 16:42











    • @WarrenYoung Doesn't SUS incorporate POSIX? This paragraph has no extension tag, and the document says things like "part of this volume of POSIX.1-2008 " throughout.

      – Random832
      Apr 30 '15 at 16:43





















    0














    It is always recommended to set ibase and obase using a single-digit number, instead of a number such as 16, since according to bc man page,




    Single digit numbers always have the value
    of the digit regardless of the value of ibase.




    This means that A,B,...,F always have the values 10,11,...,15 respectively, regardless of what the value of ibase is. You can also use F+1 to specify number 16. For example, you'd better write



    echo "ibase=F+1; obase=A; C0" | bc


    instead of writing echo "ibase=16; obase=A; C0" | bc to specify that input base is 16 and output base is 10. Or for example, if you want both ibase and obase to be 16, you'd better use



    ibase=F+1; obase=F+1


    instead of using ibase=16; obase=10. Similarly, if you're going to input your numbers in base 14 and output them in base 16, use



    ibase=E; obase=F+1


    Although bath forms have the same results, the former is less error prone, whereas the latter may lead to more confusion and error.



    The difference between the two forms especially becomes more apparent, when you are in the execution environment of bc, or you are going to write your calculations in a file, and then pass that file to bc as an argument. In such situations, you may have to change the values of ibase and obase several times, and using the latter form, can lead to serious confusion and errors. (experience it)






    share|improve this answer
























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "106"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f199615%2funderstand-ibase-and-obase-in-case-of-conversions-with-bc%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      34














      What you actually want to say is:



      $ echo "ibase=16; C0" | bc
      192


      for hex-to-decimal, and:



      $ echo "obase=16; 192" | bc
      C0


      for decimal-to-hex.



      You don't need to give both ibase and obase for any conversion involving decimal numbers, since these settings default to 10.



      You do need to give both for conversions such as binary-to-hex. In that case, I find it easiest to make sense of things if you give obase first:



      $ echo "obase=16; ibase=2; 11000000" | bc
      C0


      If you give ibase first instead, it changes the interpretation of the following obase setting, so that the command has to be:



      $ echo "ibase=2; obase=10000; 11000000" | bc
      C0


      This is because in this order, the obase value is interpreted as a binary number, so you need to give 10000₂=16 to get output in hex. That's clumsy.





      Now let’s work out why your three examples behave as they do.





      1. echo "ibase=F;obase=A;C0" | bc



        180



        That sets the input base to 15 and the output base to 10, since a single-digit value is interpreted in hex, according to POSIX. This asks bc to tell you what C0₁₅ is in base A₁₅=10, and it is correctly answering 180₁₀, though this is certainly not the question you meant to ask.




      2. echo "ibase=F;obase=10;C0" | bc



        C0



        This is a null conversion in base 15.



        Why? First, because the single F digit is interpreted in hex, as I pointed out in the previous example. But now that you've set it to base 15, the following output base setting is interpreted that way, and 10₁₅=15, so you have a null conversion from C0₁₅ to C0₁₅.



        That's right, the output isn't in hex as you were assuming, it's in base 15!



        You can prove this to yourself by trying to convert F0 instead of C0. Since there is no F digit in base 15, bc clamps it to E0, and gives E0 as the output.




      3. echo "ibase=16; obase=A; C0"



        192



        This is the only one of your three examples that likely has any practical use.



        It is changing the input base to hex first, so that you no longer need to dig into the POSIX spec to understand why A is interpreted as hex, 10 in this case. The only problem with it is that it is redundant to set the output base to A₁₆=10, since that's its default value.








      share|improve this answer






























        34














        What you actually want to say is:



        $ echo "ibase=16; C0" | bc
        192


        for hex-to-decimal, and:



        $ echo "obase=16; 192" | bc
        C0


        for decimal-to-hex.



        You don't need to give both ibase and obase for any conversion involving decimal numbers, since these settings default to 10.



        You do need to give both for conversions such as binary-to-hex. In that case, I find it easiest to make sense of things if you give obase first:



        $ echo "obase=16; ibase=2; 11000000" | bc
        C0


        If you give ibase first instead, it changes the interpretation of the following obase setting, so that the command has to be:



        $ echo "ibase=2; obase=10000; 11000000" | bc
        C0


        This is because in this order, the obase value is interpreted as a binary number, so you need to give 10000₂=16 to get output in hex. That's clumsy.





        Now let’s work out why your three examples behave as they do.





        1. echo "ibase=F;obase=A;C0" | bc



          180



          That sets the input base to 15 and the output base to 10, since a single-digit value is interpreted in hex, according to POSIX. This asks bc to tell you what C0₁₅ is in base A₁₅=10, and it is correctly answering 180₁₀, though this is certainly not the question you meant to ask.




        2. echo "ibase=F;obase=10;C0" | bc



          C0



          This is a null conversion in base 15.



          Why? First, because the single F digit is interpreted in hex, as I pointed out in the previous example. But now that you've set it to base 15, the following output base setting is interpreted that way, and 10₁₅=15, so you have a null conversion from C0₁₅ to C0₁₅.



          That's right, the output isn't in hex as you were assuming, it's in base 15!



          You can prove this to yourself by trying to convert F0 instead of C0. Since there is no F digit in base 15, bc clamps it to E0, and gives E0 as the output.




        3. echo "ibase=16; obase=A; C0"



          192



          This is the only one of your three examples that likely has any practical use.



          It is changing the input base to hex first, so that you no longer need to dig into the POSIX spec to understand why A is interpreted as hex, 10 in this case. The only problem with it is that it is redundant to set the output base to A₁₆=10, since that's its default value.








        share|improve this answer




























          34












          34








          34







          What you actually want to say is:



          $ echo "ibase=16; C0" | bc
          192


          for hex-to-decimal, and:



          $ echo "obase=16; 192" | bc
          C0


          for decimal-to-hex.



          You don't need to give both ibase and obase for any conversion involving decimal numbers, since these settings default to 10.



          You do need to give both for conversions such as binary-to-hex. In that case, I find it easiest to make sense of things if you give obase first:



          $ echo "obase=16; ibase=2; 11000000" | bc
          C0


          If you give ibase first instead, it changes the interpretation of the following obase setting, so that the command has to be:



          $ echo "ibase=2; obase=10000; 11000000" | bc
          C0


          This is because in this order, the obase value is interpreted as a binary number, so you need to give 10000₂=16 to get output in hex. That's clumsy.





          Now let’s work out why your three examples behave as they do.





          1. echo "ibase=F;obase=A;C0" | bc



            180



            That sets the input base to 15 and the output base to 10, since a single-digit value is interpreted in hex, according to POSIX. This asks bc to tell you what C0₁₅ is in base A₁₅=10, and it is correctly answering 180₁₀, though this is certainly not the question you meant to ask.




          2. echo "ibase=F;obase=10;C0" | bc



            C0



            This is a null conversion in base 15.



            Why? First, because the single F digit is interpreted in hex, as I pointed out in the previous example. But now that you've set it to base 15, the following output base setting is interpreted that way, and 10₁₅=15, so you have a null conversion from C0₁₅ to C0₁₅.



            That's right, the output isn't in hex as you were assuming, it's in base 15!



            You can prove this to yourself by trying to convert F0 instead of C0. Since there is no F digit in base 15, bc clamps it to E0, and gives E0 as the output.




          3. echo "ibase=16; obase=A; C0"



            192



            This is the only one of your three examples that likely has any practical use.



            It is changing the input base to hex first, so that you no longer need to dig into the POSIX spec to understand why A is interpreted as hex, 10 in this case. The only problem with it is that it is redundant to set the output base to A₁₆=10, since that's its default value.








          share|improve this answer















          What you actually want to say is:



          $ echo "ibase=16; C0" | bc
          192


          for hex-to-decimal, and:



          $ echo "obase=16; 192" | bc
          C0


          for decimal-to-hex.



          You don't need to give both ibase and obase for any conversion involving decimal numbers, since these settings default to 10.



          You do need to give both for conversions such as binary-to-hex. In that case, I find it easiest to make sense of things if you give obase first:



          $ echo "obase=16; ibase=2; 11000000" | bc
          C0


          If you give ibase first instead, it changes the interpretation of the following obase setting, so that the command has to be:



          $ echo "ibase=2; obase=10000; 11000000" | bc
          C0


          This is because in this order, the obase value is interpreted as a binary number, so you need to give 10000₂=16 to get output in hex. That's clumsy.





          Now let’s work out why your three examples behave as they do.





          1. echo "ibase=F;obase=A;C0" | bc



            180



            That sets the input base to 15 and the output base to 10, since a single-digit value is interpreted in hex, according to POSIX. This asks bc to tell you what C0₁₅ is in base A₁₅=10, and it is correctly answering 180₁₀, though this is certainly not the question you meant to ask.




          2. echo "ibase=F;obase=10;C0" | bc



            C0



            This is a null conversion in base 15.



            Why? First, because the single F digit is interpreted in hex, as I pointed out in the previous example. But now that you've set it to base 15, the following output base setting is interpreted that way, and 10₁₅=15, so you have a null conversion from C0₁₅ to C0₁₅.



            That's right, the output isn't in hex as you were assuming, it's in base 15!



            You can prove this to yourself by trying to convert F0 instead of C0. Since there is no F digit in base 15, bc clamps it to E0, and gives E0 as the output.




          3. echo "ibase=16; obase=A; C0"



            192



            This is the only one of your three examples that likely has any practical use.



            It is changing the input base to hex first, so that you no longer need to dig into the POSIX spec to understand why A is interpreted as hex, 10 in this case. The only problem with it is that it is redundant to set the output base to A₁₆=10, since that's its default value.









          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 49 mins ago

























          answered Apr 30 '15 at 13:07









          Warren YoungWarren Young

          57k11145150




          57k11145150

























              7














              Setting ibase means you need to set obase in that same base. Explaining your examples will show this:



              echo "ibase=F;obase=A;C0" | bc


              You set bc to consider input numbers as represented in base 15 with the "ibase=F". "obase=A" sets output numbers to base 10, which is the default.



              bc reads C0 as a base 15 number: C = 12. 12*15 = 180.





              echo "ibase=F;obase=10;C0" | bc


              In this one, you set input to base 15, and output to 10 - in base 15, so output base is 15. C0 input in base 15 is C0 output in base 15.





              echo "ibase=16;obase=A;C0" | bc


              Set input to base 16, output to base 10 (A in base 16 is 10 in base 10).



              C0 converted to base 10 is: 12*16 = 192





              My personal rule is to set obase first, so that I can use base 10. Then set ibase, also using base 10.



              Note that bc does have an ironic exception: ibase=A and obase=A always sets input and output to base 10. From the bc man page:



              Single digit numbers always have the value of the digit 
              regardless of the value of ibase.


              This behavior is enshrined in the specification of bc: From the 2004 OpenGroup bc specification:



              When either ibase or obase is assigned a single digit value from 
              the list in 'Lexical Conventions in bc', the value shall be assumed
              in hexadecimal. (For example, ibase=A sets to base ten, regardless
              of the current ibase value.) Otherwise, the behavior is undefined
              when digits greater than or equal to the value of ibase appear in
              the input.


              That's why the ibase=F setting changed your input base to base 15, and why I recommended to always set the base using base 10. Avoid confusing yourself.






              share|improve this answer


























              • @StéphaneChazelas - I have a recollection of "ibase=A" working on a SysVr3 machine in 1989 or so. I bet it goes back farther that Single Unix Spec. I couldn't quickly google up an earlier ref.

                – Bruce Ediger
                Apr 30 '15 at 14:28











              • I think that's because there are more links around to the older specs since they have been around for longer. The same kind of things happen for apache/mysql/bugzilla... documentation where google gives you the doc for the older versions first instead of the latest.

                – Stéphane Chazelas
                Apr 30 '15 at 16:21
















              7














              Setting ibase means you need to set obase in that same base. Explaining your examples will show this:



              echo "ibase=F;obase=A;C0" | bc


              You set bc to consider input numbers as represented in base 15 with the "ibase=F". "obase=A" sets output numbers to base 10, which is the default.



              bc reads C0 as a base 15 number: C = 12. 12*15 = 180.





              echo "ibase=F;obase=10;C0" | bc


              In this one, you set input to base 15, and output to 10 - in base 15, so output base is 15. C0 input in base 15 is C0 output in base 15.





              echo "ibase=16;obase=A;C0" | bc


              Set input to base 16, output to base 10 (A in base 16 is 10 in base 10).



              C0 converted to base 10 is: 12*16 = 192





              My personal rule is to set obase first, so that I can use base 10. Then set ibase, also using base 10.



              Note that bc does have an ironic exception: ibase=A and obase=A always sets input and output to base 10. From the bc man page:



              Single digit numbers always have the value of the digit 
              regardless of the value of ibase.


              This behavior is enshrined in the specification of bc: From the 2004 OpenGroup bc specification:



              When either ibase or obase is assigned a single digit value from 
              the list in 'Lexical Conventions in bc', the value shall be assumed
              in hexadecimal. (For example, ibase=A sets to base ten, regardless
              of the current ibase value.) Otherwise, the behavior is undefined
              when digits greater than or equal to the value of ibase appear in
              the input.


              That's why the ibase=F setting changed your input base to base 15, and why I recommended to always set the base using base 10. Avoid confusing yourself.






              share|improve this answer


























              • @StéphaneChazelas - I have a recollection of "ibase=A" working on a SysVr3 machine in 1989 or so. I bet it goes back farther that Single Unix Spec. I couldn't quickly google up an earlier ref.

                – Bruce Ediger
                Apr 30 '15 at 14:28











              • I think that's because there are more links around to the older specs since they have been around for longer. The same kind of things happen for apache/mysql/bugzilla... documentation where google gives you the doc for the older versions first instead of the latest.

                – Stéphane Chazelas
                Apr 30 '15 at 16:21














              7












              7








              7







              Setting ibase means you need to set obase in that same base. Explaining your examples will show this:



              echo "ibase=F;obase=A;C0" | bc


              You set bc to consider input numbers as represented in base 15 with the "ibase=F". "obase=A" sets output numbers to base 10, which is the default.



              bc reads C0 as a base 15 number: C = 12. 12*15 = 180.





              echo "ibase=F;obase=10;C0" | bc


              In this one, you set input to base 15, and output to 10 - in base 15, so output base is 15. C0 input in base 15 is C0 output in base 15.





              echo "ibase=16;obase=A;C0" | bc


              Set input to base 16, output to base 10 (A in base 16 is 10 in base 10).



              C0 converted to base 10 is: 12*16 = 192





              My personal rule is to set obase first, so that I can use base 10. Then set ibase, also using base 10.



              Note that bc does have an ironic exception: ibase=A and obase=A always sets input and output to base 10. From the bc man page:



              Single digit numbers always have the value of the digit 
              regardless of the value of ibase.


              This behavior is enshrined in the specification of bc: From the 2004 OpenGroup bc specification:



              When either ibase or obase is assigned a single digit value from 
              the list in 'Lexical Conventions in bc', the value shall be assumed
              in hexadecimal. (For example, ibase=A sets to base ten, regardless
              of the current ibase value.) Otherwise, the behavior is undefined
              when digits greater than or equal to the value of ibase appear in
              the input.


              That's why the ibase=F setting changed your input base to base 15, and why I recommended to always set the base using base 10. Avoid confusing yourself.






              share|improve this answer















              Setting ibase means you need to set obase in that same base. Explaining your examples will show this:



              echo "ibase=F;obase=A;C0" | bc


              You set bc to consider input numbers as represented in base 15 with the "ibase=F". "obase=A" sets output numbers to base 10, which is the default.



              bc reads C0 as a base 15 number: C = 12. 12*15 = 180.





              echo "ibase=F;obase=10;C0" | bc


              In this one, you set input to base 15, and output to 10 - in base 15, so output base is 15. C0 input in base 15 is C0 output in base 15.





              echo "ibase=16;obase=A;C0" | bc


              Set input to base 16, output to base 10 (A in base 16 is 10 in base 10).



              C0 converted to base 10 is: 12*16 = 192





              My personal rule is to set obase first, so that I can use base 10. Then set ibase, also using base 10.



              Note that bc does have an ironic exception: ibase=A and obase=A always sets input and output to base 10. From the bc man page:



              Single digit numbers always have the value of the digit 
              regardless of the value of ibase.


              This behavior is enshrined in the specification of bc: From the 2004 OpenGroup bc specification:



              When either ibase or obase is assigned a single digit value from 
              the list in 'Lexical Conventions in bc', the value shall be assumed
              in hexadecimal. (For example, ibase=A sets to base ten, regardless
              of the current ibase value.) Otherwise, the behavior is undefined
              when digits greater than or equal to the value of ibase appear in
              the input.


              That's why the ibase=F setting changed your input base to base 15, and why I recommended to always set the base using base 10. Avoid confusing yourself.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited May 1 '15 at 0:02

























              answered Apr 30 '15 at 13:14









              Bruce EdigerBruce Ediger

              36.1k671120




              36.1k671120













              • @StéphaneChazelas - I have a recollection of "ibase=A" working on a SysVr3 machine in 1989 or so. I bet it goes back farther that Single Unix Spec. I couldn't quickly google up an earlier ref.

                – Bruce Ediger
                Apr 30 '15 at 14:28











              • I think that's because there are more links around to the older specs since they have been around for longer. The same kind of things happen for apache/mysql/bugzilla... documentation where google gives you the doc for the older versions first instead of the latest.

                – Stéphane Chazelas
                Apr 30 '15 at 16:21



















              • @StéphaneChazelas - I have a recollection of "ibase=A" working on a SysVr3 machine in 1989 or so. I bet it goes back farther that Single Unix Spec. I couldn't quickly google up an earlier ref.

                – Bruce Ediger
                Apr 30 '15 at 14:28











              • I think that's because there are more links around to the older specs since they have been around for longer. The same kind of things happen for apache/mysql/bugzilla... documentation where google gives you the doc for the older versions first instead of the latest.

                – Stéphane Chazelas
                Apr 30 '15 at 16:21

















              @StéphaneChazelas - I have a recollection of "ibase=A" working on a SysVr3 machine in 1989 or so. I bet it goes back farther that Single Unix Spec. I couldn't quickly google up an earlier ref.

              – Bruce Ediger
              Apr 30 '15 at 14:28





              @StéphaneChazelas - I have a recollection of "ibase=A" working on a SysVr3 machine in 1989 or so. I bet it goes back farther that Single Unix Spec. I couldn't quickly google up an earlier ref.

              – Bruce Ediger
              Apr 30 '15 at 14:28













              I think that's because there are more links around to the older specs since they have been around for longer. The same kind of things happen for apache/mysql/bugzilla... documentation where google gives you the doc for the older versions first instead of the latest.

              – Stéphane Chazelas
              Apr 30 '15 at 16:21





              I think that's because there are more links around to the older specs since they have been around for longer. The same kind of things happen for apache/mysql/bugzilla... documentation where google gives you the doc for the older versions first instead of the latest.

              – Stéphane Chazelas
              Apr 30 '15 at 16:21











              5














              All numbers are interpreted by GNU bc as the current input base that is in effect for the statement the number appears in. When you use a digit outside the current input interpret them as the highest digit available in the base (9 in decimal) when part of a multiple digit number, or as their normal values when used as a single digit number (A == 10 in decimal).



              From the GNU bc manual:




              Single digit numbers always have the value of the digit regardless of the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1. This makes the number FFF always be the largest 3 digit number of the input base.




              However, you should be aware that the POSIX standard only defines this behavior for assignments to ibase and obase, and not in any other context.



              From the SUS specification on bc:




              When either ibase or obase is assigned a single digit value from the list in Lexical Conventions in bc , the value shall be assumed in hexadecimal. (For example, ibase=A sets to base ten, regardless of the current ibase value.) Otherwise, the behavior is undefined when digits greater than or equal to the value of ibase appear in the input. Both ibase and obase shall have initial values of 10.




              The key factor you are missing is that F is not in fact sixteen, but is actually fifteen, so when you are setting ibase=F you are setting the input base to fifteen.



              Therefore, to portably set the ibase to hexadecimal from an unknown state, you therefore need to use two statements: ibase=A; ibase=16. However, in the beginning of the program you can rely on it being decimal and simply use ibase=16.






              share|improve this answer


























              • +1: Cute trick with ibase=A; ibase=16.

                – Warren Young
                Apr 30 '15 at 16:23











              • That's SUSv3, not SUSv6. SUSv4 is at pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

                – Stéphane Chazelas
                Apr 30 '15 at 16:25











              • I'd always thought the 6 and 7 in the headers were the version. I've never seen anything different - what are issue #1-5?

                – Random832
                Apr 30 '15 at 16:29











              • @Random832: SUS and POSIX aren't the same thing.

                – Warren Young
                Apr 30 '15 at 16:42











              • @WarrenYoung Doesn't SUS incorporate POSIX? This paragraph has no extension tag, and the document says things like "part of this volume of POSIX.1-2008 " throughout.

                – Random832
                Apr 30 '15 at 16:43


















              5














              All numbers are interpreted by GNU bc as the current input base that is in effect for the statement the number appears in. When you use a digit outside the current input interpret them as the highest digit available in the base (9 in decimal) when part of a multiple digit number, or as their normal values when used as a single digit number (A == 10 in decimal).



              From the GNU bc manual:




              Single digit numbers always have the value of the digit regardless of the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1. This makes the number FFF always be the largest 3 digit number of the input base.




              However, you should be aware that the POSIX standard only defines this behavior for assignments to ibase and obase, and not in any other context.



              From the SUS specification on bc:




              When either ibase or obase is assigned a single digit value from the list in Lexical Conventions in bc , the value shall be assumed in hexadecimal. (For example, ibase=A sets to base ten, regardless of the current ibase value.) Otherwise, the behavior is undefined when digits greater than or equal to the value of ibase appear in the input. Both ibase and obase shall have initial values of 10.




              The key factor you are missing is that F is not in fact sixteen, but is actually fifteen, so when you are setting ibase=F you are setting the input base to fifteen.



              Therefore, to portably set the ibase to hexadecimal from an unknown state, you therefore need to use two statements: ibase=A; ibase=16. However, in the beginning of the program you can rely on it being decimal and simply use ibase=16.






              share|improve this answer


























              • +1: Cute trick with ibase=A; ibase=16.

                – Warren Young
                Apr 30 '15 at 16:23











              • That's SUSv3, not SUSv6. SUSv4 is at pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

                – Stéphane Chazelas
                Apr 30 '15 at 16:25











              • I'd always thought the 6 and 7 in the headers were the version. I've never seen anything different - what are issue #1-5?

                – Random832
                Apr 30 '15 at 16:29











              • @Random832: SUS and POSIX aren't the same thing.

                – Warren Young
                Apr 30 '15 at 16:42











              • @WarrenYoung Doesn't SUS incorporate POSIX? This paragraph has no extension tag, and the document says things like "part of this volume of POSIX.1-2008 " throughout.

                – Random832
                Apr 30 '15 at 16:43
















              5












              5








              5







              All numbers are interpreted by GNU bc as the current input base that is in effect for the statement the number appears in. When you use a digit outside the current input interpret them as the highest digit available in the base (9 in decimal) when part of a multiple digit number, or as their normal values when used as a single digit number (A == 10 in decimal).



              From the GNU bc manual:




              Single digit numbers always have the value of the digit regardless of the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1. This makes the number FFF always be the largest 3 digit number of the input base.




              However, you should be aware that the POSIX standard only defines this behavior for assignments to ibase and obase, and not in any other context.



              From the SUS specification on bc:




              When either ibase or obase is assigned a single digit value from the list in Lexical Conventions in bc , the value shall be assumed in hexadecimal. (For example, ibase=A sets to base ten, regardless of the current ibase value.) Otherwise, the behavior is undefined when digits greater than or equal to the value of ibase appear in the input. Both ibase and obase shall have initial values of 10.




              The key factor you are missing is that F is not in fact sixteen, but is actually fifteen, so when you are setting ibase=F you are setting the input base to fifteen.



              Therefore, to portably set the ibase to hexadecimal from an unknown state, you therefore need to use two statements: ibase=A; ibase=16. However, in the beginning of the program you can rely on it being decimal and simply use ibase=16.






              share|improve this answer















              All numbers are interpreted by GNU bc as the current input base that is in effect for the statement the number appears in. When you use a digit outside the current input interpret them as the highest digit available in the base (9 in decimal) when part of a multiple digit number, or as their normal values when used as a single digit number (A == 10 in decimal).



              From the GNU bc manual:




              Single digit numbers always have the value of the digit regardless of the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1. This makes the number FFF always be the largest 3 digit number of the input base.




              However, you should be aware that the POSIX standard only defines this behavior for assignments to ibase and obase, and not in any other context.



              From the SUS specification on bc:




              When either ibase or obase is assigned a single digit value from the list in Lexical Conventions in bc , the value shall be assumed in hexadecimal. (For example, ibase=A sets to base ten, regardless of the current ibase value.) Otherwise, the behavior is undefined when digits greater than or equal to the value of ibase appear in the input. Both ibase and obase shall have initial values of 10.




              The key factor you are missing is that F is not in fact sixteen, but is actually fifteen, so when you are setting ibase=F you are setting the input base to fifteen.



              Therefore, to portably set the ibase to hexadecimal from an unknown state, you therefore need to use two statements: ibase=A; ibase=16. However, in the beginning of the program you can rely on it being decimal and simply use ibase=16.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 30 '15 at 16:30

























              answered Apr 30 '15 at 16:11









              Random832Random832

              8,65012536




              8,65012536













              • +1: Cute trick with ibase=A; ibase=16.

                – Warren Young
                Apr 30 '15 at 16:23











              • That's SUSv3, not SUSv6. SUSv4 is at pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

                – Stéphane Chazelas
                Apr 30 '15 at 16:25











              • I'd always thought the 6 and 7 in the headers were the version. I've never seen anything different - what are issue #1-5?

                – Random832
                Apr 30 '15 at 16:29











              • @Random832: SUS and POSIX aren't the same thing.

                – Warren Young
                Apr 30 '15 at 16:42











              • @WarrenYoung Doesn't SUS incorporate POSIX? This paragraph has no extension tag, and the document says things like "part of this volume of POSIX.1-2008 " throughout.

                – Random832
                Apr 30 '15 at 16:43





















              • +1: Cute trick with ibase=A; ibase=16.

                – Warren Young
                Apr 30 '15 at 16:23











              • That's SUSv3, not SUSv6. SUSv4 is at pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

                – Stéphane Chazelas
                Apr 30 '15 at 16:25











              • I'd always thought the 6 and 7 in the headers were the version. I've never seen anything different - what are issue #1-5?

                – Random832
                Apr 30 '15 at 16:29











              • @Random832: SUS and POSIX aren't the same thing.

                – Warren Young
                Apr 30 '15 at 16:42











              • @WarrenYoung Doesn't SUS incorporate POSIX? This paragraph has no extension tag, and the document says things like "part of this volume of POSIX.1-2008 " throughout.

                – Random832
                Apr 30 '15 at 16:43



















              +1: Cute trick with ibase=A; ibase=16.

              – Warren Young
              Apr 30 '15 at 16:23





              +1: Cute trick with ibase=A; ibase=16.

              – Warren Young
              Apr 30 '15 at 16:23













              That's SUSv3, not SUSv6. SUSv4 is at pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

              – Stéphane Chazelas
              Apr 30 '15 at 16:25





              That's SUSv3, not SUSv6. SUSv4 is at pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

              – Stéphane Chazelas
              Apr 30 '15 at 16:25













              I'd always thought the 6 and 7 in the headers were the version. I've never seen anything different - what are issue #1-5?

              – Random832
              Apr 30 '15 at 16:29





              I'd always thought the 6 and 7 in the headers were the version. I've never seen anything different - what are issue #1-5?

              – Random832
              Apr 30 '15 at 16:29













              @Random832: SUS and POSIX aren't the same thing.

              – Warren Young
              Apr 30 '15 at 16:42





              @Random832: SUS and POSIX aren't the same thing.

              – Warren Young
              Apr 30 '15 at 16:42













              @WarrenYoung Doesn't SUS incorporate POSIX? This paragraph has no extension tag, and the document says things like "part of this volume of POSIX.1-2008 " throughout.

              – Random832
              Apr 30 '15 at 16:43







              @WarrenYoung Doesn't SUS incorporate POSIX? This paragraph has no extension tag, and the document says things like "part of this volume of POSIX.1-2008 " throughout.

              – Random832
              Apr 30 '15 at 16:43













              0














              It is always recommended to set ibase and obase using a single-digit number, instead of a number such as 16, since according to bc man page,




              Single digit numbers always have the value
              of the digit regardless of the value of ibase.




              This means that A,B,...,F always have the values 10,11,...,15 respectively, regardless of what the value of ibase is. You can also use F+1 to specify number 16. For example, you'd better write



              echo "ibase=F+1; obase=A; C0" | bc


              instead of writing echo "ibase=16; obase=A; C0" | bc to specify that input base is 16 and output base is 10. Or for example, if you want both ibase and obase to be 16, you'd better use



              ibase=F+1; obase=F+1


              instead of using ibase=16; obase=10. Similarly, if you're going to input your numbers in base 14 and output them in base 16, use



              ibase=E; obase=F+1


              Although bath forms have the same results, the former is less error prone, whereas the latter may lead to more confusion and error.



              The difference between the two forms especially becomes more apparent, when you are in the execution environment of bc, or you are going to write your calculations in a file, and then pass that file to bc as an argument. In such situations, you may have to change the values of ibase and obase several times, and using the latter form, can lead to serious confusion and errors. (experience it)






              share|improve this answer




























                0














                It is always recommended to set ibase and obase using a single-digit number, instead of a number such as 16, since according to bc man page,




                Single digit numbers always have the value
                of the digit regardless of the value of ibase.




                This means that A,B,...,F always have the values 10,11,...,15 respectively, regardless of what the value of ibase is. You can also use F+1 to specify number 16. For example, you'd better write



                echo "ibase=F+1; obase=A; C0" | bc


                instead of writing echo "ibase=16; obase=A; C0" | bc to specify that input base is 16 and output base is 10. Or for example, if you want both ibase and obase to be 16, you'd better use



                ibase=F+1; obase=F+1


                instead of using ibase=16; obase=10. Similarly, if you're going to input your numbers in base 14 and output them in base 16, use



                ibase=E; obase=F+1


                Although bath forms have the same results, the former is less error prone, whereas the latter may lead to more confusion and error.



                The difference between the two forms especially becomes more apparent, when you are in the execution environment of bc, or you are going to write your calculations in a file, and then pass that file to bc as an argument. In such situations, you may have to change the values of ibase and obase several times, and using the latter form, can lead to serious confusion and errors. (experience it)






                share|improve this answer


























                  0












                  0








                  0







                  It is always recommended to set ibase and obase using a single-digit number, instead of a number such as 16, since according to bc man page,




                  Single digit numbers always have the value
                  of the digit regardless of the value of ibase.




                  This means that A,B,...,F always have the values 10,11,...,15 respectively, regardless of what the value of ibase is. You can also use F+1 to specify number 16. For example, you'd better write



                  echo "ibase=F+1; obase=A; C0" | bc


                  instead of writing echo "ibase=16; obase=A; C0" | bc to specify that input base is 16 and output base is 10. Or for example, if you want both ibase and obase to be 16, you'd better use



                  ibase=F+1; obase=F+1


                  instead of using ibase=16; obase=10. Similarly, if you're going to input your numbers in base 14 and output them in base 16, use



                  ibase=E; obase=F+1


                  Although bath forms have the same results, the former is less error prone, whereas the latter may lead to more confusion and error.



                  The difference between the two forms especially becomes more apparent, when you are in the execution environment of bc, or you are going to write your calculations in a file, and then pass that file to bc as an argument. In such situations, you may have to change the values of ibase and obase several times, and using the latter form, can lead to serious confusion and errors. (experience it)






                  share|improve this answer













                  It is always recommended to set ibase and obase using a single-digit number, instead of a number such as 16, since according to bc man page,




                  Single digit numbers always have the value
                  of the digit regardless of the value of ibase.




                  This means that A,B,...,F always have the values 10,11,...,15 respectively, regardless of what the value of ibase is. You can also use F+1 to specify number 16. For example, you'd better write



                  echo "ibase=F+1; obase=A; C0" | bc


                  instead of writing echo "ibase=16; obase=A; C0" | bc to specify that input base is 16 and output base is 10. Or for example, if you want both ibase and obase to be 16, you'd better use



                  ibase=F+1; obase=F+1


                  instead of using ibase=16; obase=10. Similarly, if you're going to input your numbers in base 14 and output them in base 16, use



                  ibase=E; obase=F+1


                  Although bath forms have the same results, the former is less error prone, whereas the latter may lead to more confusion and error.



                  The difference between the two forms especially becomes more apparent, when you are in the execution environment of bc, or you are going to write your calculations in a file, and then pass that file to bc as an argument. In such situations, you may have to change the values of ibase and obase several times, and using the latter form, can lead to serious confusion and errors. (experience it)







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 31 '18 at 18:13









                  Hedayat MahdipourHedayat Mahdipour

                  182




                  182






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f199615%2funderstand-ibase-and-obase-in-case-of-conversions-with-bc%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

                      Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

                      Nicolae Petrescu-Găină Cuprins Biografie | Opera | In memoriam | Varia | Controverse, incertitudini...