Arduino: incorrect calculation of long integer












1














I'm doing a simple calculation with integers (on Arduino with ESP8266 12E), but I can't get the expected result and can't find the error. Can someone guide me?



#define A      200
#define B A * 62
#define C 500

void setup() {
Serial.begin(9600);
Serial.println("");

unsigned long aux = 0;

aux = (B * 500) / C; // (12400 * 500) / 500 = 12400
Serial.printf("aux = %dn", aux);
aux = aux * C; // 12400 * 500 = 6200000
Serial.printf("aux = %dn", aux);

// ERROR: Should result in "500", but is resulting in "1922000"
aux = aux / B; // 6200000 / 12400 = 500

Serial.printf("aux = %dn", aux); // It's printing "1922000"
}









share|improve this question













migrated from electronics.stackexchange.com 2 days ago


This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.




















    1














    I'm doing a simple calculation with integers (on Arduino with ESP8266 12E), but I can't get the expected result and can't find the error. Can someone guide me?



    #define A      200
    #define B A * 62
    #define C 500

    void setup() {
    Serial.begin(9600);
    Serial.println("");

    unsigned long aux = 0;

    aux = (B * 500) / C; // (12400 * 500) / 500 = 12400
    Serial.printf("aux = %dn", aux);
    aux = aux * C; // 12400 * 500 = 6200000
    Serial.printf("aux = %dn", aux);

    // ERROR: Should result in "500", but is resulting in "1922000"
    aux = aux / B; // 6200000 / 12400 = 500

    Serial.printf("aux = %dn", aux); // It's printing "1922000"
    }









    share|improve this question













    migrated from electronics.stackexchange.com 2 days ago


    This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.


















      1












      1








      1







      I'm doing a simple calculation with integers (on Arduino with ESP8266 12E), but I can't get the expected result and can't find the error. Can someone guide me?



      #define A      200
      #define B A * 62
      #define C 500

      void setup() {
      Serial.begin(9600);
      Serial.println("");

      unsigned long aux = 0;

      aux = (B * 500) / C; // (12400 * 500) / 500 = 12400
      Serial.printf("aux = %dn", aux);
      aux = aux * C; // 12400 * 500 = 6200000
      Serial.printf("aux = %dn", aux);

      // ERROR: Should result in "500", but is resulting in "1922000"
      aux = aux / B; // 6200000 / 12400 = 500

      Serial.printf("aux = %dn", aux); // It's printing "1922000"
      }









      share|improve this question













      I'm doing a simple calculation with integers (on Arduino with ESP8266 12E), but I can't get the expected result and can't find the error. Can someone guide me?



      #define A      200
      #define B A * 62
      #define C 500

      void setup() {
      Serial.begin(9600);
      Serial.println("");

      unsigned long aux = 0;

      aux = (B * 500) / C; // (12400 * 500) / 500 = 12400
      Serial.printf("aux = %dn", aux);
      aux = aux * C; // 12400 * 500 = 6200000
      Serial.printf("aux = %dn", aux);

      // ERROR: Should result in "500", but is resulting in "1922000"
      aux = aux / B; // 6200000 / 12400 = 500

      Serial.printf("aux = %dn", aux); // It's printing "1922000"
      }






      esp8266






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 2 days ago









      wBB

      1134




      1134




      migrated from electronics.stackexchange.com 2 days ago


      This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.






      migrated from electronics.stackexchange.com 2 days ago


      This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.
























          3 Answers
          3






          active

          oldest

          votes


















          11














          In your #define of B you missed parenthesis (). Change your definition to:



          #define B      (A * 62)


          Without parenthesis you first divide 6200000 by 200 and then multiply result by 62, which is not what you intend.






          share|improve this answer





















          • Dude, you're 100% right. I've spent several hours trying to figure out what was wrong ... Thank you so much!
            – wBB
            2 days ago






          • 2




            @wBB remember that in C, macros are replaced in the code, exactly as you wrote them, in the preprocessor step before the code gets compiled. So it helps as a sanity-check in these cases to expand the macros yourself in your code to see if you're getting what you intended.
            – brhans
            2 days ago










          • It really is was my lack of exeperience in C that led me to the problem. Thanks!
            – wBB
            2 days ago



















          3














          Fully-parenthesizing macros (as noted in answer by dmz) solves one class of problem.



          Another thing you should do is, in any arithmetic expression which involves literal constants, use the L suffix on at least one of the constants involved if there's any chance the result will exceed 32767 (the maximum guaranteed-representable value for int). The type of an arithmetic operation in C is based on the types of the operands of that operation only; the type of the variable to which the result is assigned is irrelevant.






          share|improve this answer

















          • 2




            ...and the format specifier for an unsigned long is %lu not %d - the compiler for the asker's esp8266 uses a 32-bit int so they get away with some things they would not on an ATmega-based Arduino where an int is the minimum 16 bit size allowed by the specification.
            – Chris Stratton
            2 days ago










          • @mlp usually I use a typecast on almost everything. Example: int J = -1, typecast (unsigned char) J //prints 255. When you talk about the suffix L, what do you mean? Can you give an example?
            – wBB
            2 days ago












          • @ChrisStratton, thanks for explanation.
            – wBB
            2 days ago



















          1














          As explained in previous answers, fully parenthesizing the macros is the
          standard solution to this problem in C. However, on Arduino you are
          programming in C++, and in C++ it is considered good practice to replace
          this usage of #define by explicit constants:



          const int A = 200;
          const int B = A * 62;
          const int C = 500;


          Not only this makes the initial problem go away, it also provides some
          type safety: you can choose to give these constants other types (e.g.
          long) if appropriate.






          share|improve this answer





















          • Some compilers will interpret "const" as a variable going into program memory which then in turn results in issues with memory spaces. Consts offer type protection, which can also be (partially) achieved by casting inside the define "#define A ((int)200)" for instance.
            – le_top
            yesterday










          • @le_top: Do you have a specific example of the kind of “issues with memory spaces” you can get? I doubt you could find an example that does not invoke undefined behavior.
            – Edgar Bonet
            yesterday










          • Something along these lines for example: "const int a=100; int b=200; void setB(const int *c) {b=c;} void ex1() {setB(&a);}" . But there are other cases. When "const" puts "a" in ROM, some embedded compilers can not cope with this kind of assignment and do not report all violating cases. So I tend to put "CONST" if there is a future risk for this. (with a "#define CONST const" if possible).
            – le_top
            17 hours ago










          • @le_top: I guess you mean b=*c. This sounds like a compiler bug to me. What compiler had issues with this? I tried your code on avr-gcc, and it had no issues, even when I replaced const by __flash const, which has the effect of putting a in flash.
            – Edgar Bonet
            14 hours ago










          • Yes, b=*c. It will depend on the compiler and the uC. I file reports when I find bugs - when the compiler does not warn about it it is a bug, but otherwise it is a documented limitation.On Arduino you should use PROGMEM rather than __flash. I do not want to put a specific compilrer forward, my comment was mainly about warning that there are compilers for embedded systems that interpret const in a way that breaks code compatibility. That's also why you're required to add "__flash" to get the variable in FLASH - keeping it in RAM eases code generation (and speed) for those processors.
            – le_top
            12 mins ago











          Your Answer






          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("schematics", function () {
          StackExchange.schematics.init();
          });
          }, "cicuitlab");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "540"
          };
          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%2farduino.stackexchange.com%2fquestions%2f60097%2farduino-incorrect-calculation-of-long-integer%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          11














          In your #define of B you missed parenthesis (). Change your definition to:



          #define B      (A * 62)


          Without parenthesis you first divide 6200000 by 200 and then multiply result by 62, which is not what you intend.






          share|improve this answer





















          • Dude, you're 100% right. I've spent several hours trying to figure out what was wrong ... Thank you so much!
            – wBB
            2 days ago






          • 2




            @wBB remember that in C, macros are replaced in the code, exactly as you wrote them, in the preprocessor step before the code gets compiled. So it helps as a sanity-check in these cases to expand the macros yourself in your code to see if you're getting what you intended.
            – brhans
            2 days ago










          • It really is was my lack of exeperience in C that led me to the problem. Thanks!
            – wBB
            2 days ago
















          11














          In your #define of B you missed parenthesis (). Change your definition to:



          #define B      (A * 62)


          Without parenthesis you first divide 6200000 by 200 and then multiply result by 62, which is not what you intend.






          share|improve this answer





















          • Dude, you're 100% right. I've spent several hours trying to figure out what was wrong ... Thank you so much!
            – wBB
            2 days ago






          • 2




            @wBB remember that in C, macros are replaced in the code, exactly as you wrote them, in the preprocessor step before the code gets compiled. So it helps as a sanity-check in these cases to expand the macros yourself in your code to see if you're getting what you intended.
            – brhans
            2 days ago










          • It really is was my lack of exeperience in C that led me to the problem. Thanks!
            – wBB
            2 days ago














          11












          11








          11






          In your #define of B you missed parenthesis (). Change your definition to:



          #define B      (A * 62)


          Without parenthesis you first divide 6200000 by 200 and then multiply result by 62, which is not what you intend.






          share|improve this answer












          In your #define of B you missed parenthesis (). Change your definition to:



          #define B      (A * 62)


          Without parenthesis you first divide 6200000 by 200 and then multiply result by 62, which is not what you intend.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 2 days ago







          dmz



















          • Dude, you're 100% right. I've spent several hours trying to figure out what was wrong ... Thank you so much!
            – wBB
            2 days ago






          • 2




            @wBB remember that in C, macros are replaced in the code, exactly as you wrote them, in the preprocessor step before the code gets compiled. So it helps as a sanity-check in these cases to expand the macros yourself in your code to see if you're getting what you intended.
            – brhans
            2 days ago










          • It really is was my lack of exeperience in C that led me to the problem. Thanks!
            – wBB
            2 days ago


















          • Dude, you're 100% right. I've spent several hours trying to figure out what was wrong ... Thank you so much!
            – wBB
            2 days ago






          • 2




            @wBB remember that in C, macros are replaced in the code, exactly as you wrote them, in the preprocessor step before the code gets compiled. So it helps as a sanity-check in these cases to expand the macros yourself in your code to see if you're getting what you intended.
            – brhans
            2 days ago










          • It really is was my lack of exeperience in C that led me to the problem. Thanks!
            – wBB
            2 days ago
















          Dude, you're 100% right. I've spent several hours trying to figure out what was wrong ... Thank you so much!
          – wBB
          2 days ago




          Dude, you're 100% right. I've spent several hours trying to figure out what was wrong ... Thank you so much!
          – wBB
          2 days ago




          2




          2




          @wBB remember that in C, macros are replaced in the code, exactly as you wrote them, in the preprocessor step before the code gets compiled. So it helps as a sanity-check in these cases to expand the macros yourself in your code to see if you're getting what you intended.
          – brhans
          2 days ago




          @wBB remember that in C, macros are replaced in the code, exactly as you wrote them, in the preprocessor step before the code gets compiled. So it helps as a sanity-check in these cases to expand the macros yourself in your code to see if you're getting what you intended.
          – brhans
          2 days ago












          It really is was my lack of exeperience in C that led me to the problem. Thanks!
          – wBB
          2 days ago




          It really is was my lack of exeperience in C that led me to the problem. Thanks!
          – wBB
          2 days ago











          3














          Fully-parenthesizing macros (as noted in answer by dmz) solves one class of problem.



          Another thing you should do is, in any arithmetic expression which involves literal constants, use the L suffix on at least one of the constants involved if there's any chance the result will exceed 32767 (the maximum guaranteed-representable value for int). The type of an arithmetic operation in C is based on the types of the operands of that operation only; the type of the variable to which the result is assigned is irrelevant.






          share|improve this answer

















          • 2




            ...and the format specifier for an unsigned long is %lu not %d - the compiler for the asker's esp8266 uses a 32-bit int so they get away with some things they would not on an ATmega-based Arduino where an int is the minimum 16 bit size allowed by the specification.
            – Chris Stratton
            2 days ago










          • @mlp usually I use a typecast on almost everything. Example: int J = -1, typecast (unsigned char) J //prints 255. When you talk about the suffix L, what do you mean? Can you give an example?
            – wBB
            2 days ago












          • @ChrisStratton, thanks for explanation.
            – wBB
            2 days ago
















          3














          Fully-parenthesizing macros (as noted in answer by dmz) solves one class of problem.



          Another thing you should do is, in any arithmetic expression which involves literal constants, use the L suffix on at least one of the constants involved if there's any chance the result will exceed 32767 (the maximum guaranteed-representable value for int). The type of an arithmetic operation in C is based on the types of the operands of that operation only; the type of the variable to which the result is assigned is irrelevant.






          share|improve this answer

















          • 2




            ...and the format specifier for an unsigned long is %lu not %d - the compiler for the asker's esp8266 uses a 32-bit int so they get away with some things they would not on an ATmega-based Arduino where an int is the minimum 16 bit size allowed by the specification.
            – Chris Stratton
            2 days ago










          • @mlp usually I use a typecast on almost everything. Example: int J = -1, typecast (unsigned char) J //prints 255. When you talk about the suffix L, what do you mean? Can you give an example?
            – wBB
            2 days ago












          • @ChrisStratton, thanks for explanation.
            – wBB
            2 days ago














          3












          3








          3






          Fully-parenthesizing macros (as noted in answer by dmz) solves one class of problem.



          Another thing you should do is, in any arithmetic expression which involves literal constants, use the L suffix on at least one of the constants involved if there's any chance the result will exceed 32767 (the maximum guaranteed-representable value for int). The type of an arithmetic operation in C is based on the types of the operands of that operation only; the type of the variable to which the result is assigned is irrelevant.






          share|improve this answer












          Fully-parenthesizing macros (as noted in answer by dmz) solves one class of problem.



          Another thing you should do is, in any arithmetic expression which involves literal constants, use the L suffix on at least one of the constants involved if there's any chance the result will exceed 32767 (the maximum guaranteed-representable value for int). The type of an arithmetic operation in C is based on the types of the operands of that operation only; the type of the variable to which the result is assigned is irrelevant.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 2 days ago









          mlp

          1311




          1311








          • 2




            ...and the format specifier for an unsigned long is %lu not %d - the compiler for the asker's esp8266 uses a 32-bit int so they get away with some things they would not on an ATmega-based Arduino where an int is the minimum 16 bit size allowed by the specification.
            – Chris Stratton
            2 days ago










          • @mlp usually I use a typecast on almost everything. Example: int J = -1, typecast (unsigned char) J //prints 255. When you talk about the suffix L, what do you mean? Can you give an example?
            – wBB
            2 days ago












          • @ChrisStratton, thanks for explanation.
            – wBB
            2 days ago














          • 2




            ...and the format specifier for an unsigned long is %lu not %d - the compiler for the asker's esp8266 uses a 32-bit int so they get away with some things they would not on an ATmega-based Arduino where an int is the minimum 16 bit size allowed by the specification.
            – Chris Stratton
            2 days ago










          • @mlp usually I use a typecast on almost everything. Example: int J = -1, typecast (unsigned char) J //prints 255. When you talk about the suffix L, what do you mean? Can you give an example?
            – wBB
            2 days ago












          • @ChrisStratton, thanks for explanation.
            – wBB
            2 days ago








          2




          2




          ...and the format specifier for an unsigned long is %lu not %d - the compiler for the asker's esp8266 uses a 32-bit int so they get away with some things they would not on an ATmega-based Arduino where an int is the minimum 16 bit size allowed by the specification.
          – Chris Stratton
          2 days ago




          ...and the format specifier for an unsigned long is %lu not %d - the compiler for the asker's esp8266 uses a 32-bit int so they get away with some things they would not on an ATmega-based Arduino where an int is the minimum 16 bit size allowed by the specification.
          – Chris Stratton
          2 days ago












          @mlp usually I use a typecast on almost everything. Example: int J = -1, typecast (unsigned char) J //prints 255. When you talk about the suffix L, what do you mean? Can you give an example?
          – wBB
          2 days ago






          @mlp usually I use a typecast on almost everything. Example: int J = -1, typecast (unsigned char) J //prints 255. When you talk about the suffix L, what do you mean? Can you give an example?
          – wBB
          2 days ago














          @ChrisStratton, thanks for explanation.
          – wBB
          2 days ago




          @ChrisStratton, thanks for explanation.
          – wBB
          2 days ago











          1














          As explained in previous answers, fully parenthesizing the macros is the
          standard solution to this problem in C. However, on Arduino you are
          programming in C++, and in C++ it is considered good practice to replace
          this usage of #define by explicit constants:



          const int A = 200;
          const int B = A * 62;
          const int C = 500;


          Not only this makes the initial problem go away, it also provides some
          type safety: you can choose to give these constants other types (e.g.
          long) if appropriate.






          share|improve this answer





















          • Some compilers will interpret "const" as a variable going into program memory which then in turn results in issues with memory spaces. Consts offer type protection, which can also be (partially) achieved by casting inside the define "#define A ((int)200)" for instance.
            – le_top
            yesterday










          • @le_top: Do you have a specific example of the kind of “issues with memory spaces” you can get? I doubt you could find an example that does not invoke undefined behavior.
            – Edgar Bonet
            yesterday










          • Something along these lines for example: "const int a=100; int b=200; void setB(const int *c) {b=c;} void ex1() {setB(&a);}" . But there are other cases. When "const" puts "a" in ROM, some embedded compilers can not cope with this kind of assignment and do not report all violating cases. So I tend to put "CONST" if there is a future risk for this. (with a "#define CONST const" if possible).
            – le_top
            17 hours ago










          • @le_top: I guess you mean b=*c. This sounds like a compiler bug to me. What compiler had issues with this? I tried your code on avr-gcc, and it had no issues, even when I replaced const by __flash const, which has the effect of putting a in flash.
            – Edgar Bonet
            14 hours ago










          • Yes, b=*c. It will depend on the compiler and the uC. I file reports when I find bugs - when the compiler does not warn about it it is a bug, but otherwise it is a documented limitation.On Arduino you should use PROGMEM rather than __flash. I do not want to put a specific compilrer forward, my comment was mainly about warning that there are compilers for embedded systems that interpret const in a way that breaks code compatibility. That's also why you're required to add "__flash" to get the variable in FLASH - keeping it in RAM eases code generation (and speed) for those processors.
            – le_top
            12 mins ago
















          1














          As explained in previous answers, fully parenthesizing the macros is the
          standard solution to this problem in C. However, on Arduino you are
          programming in C++, and in C++ it is considered good practice to replace
          this usage of #define by explicit constants:



          const int A = 200;
          const int B = A * 62;
          const int C = 500;


          Not only this makes the initial problem go away, it also provides some
          type safety: you can choose to give these constants other types (e.g.
          long) if appropriate.






          share|improve this answer





















          • Some compilers will interpret "const" as a variable going into program memory which then in turn results in issues with memory spaces. Consts offer type protection, which can also be (partially) achieved by casting inside the define "#define A ((int)200)" for instance.
            – le_top
            yesterday










          • @le_top: Do you have a specific example of the kind of “issues with memory spaces” you can get? I doubt you could find an example that does not invoke undefined behavior.
            – Edgar Bonet
            yesterday










          • Something along these lines for example: "const int a=100; int b=200; void setB(const int *c) {b=c;} void ex1() {setB(&a);}" . But there are other cases. When "const" puts "a" in ROM, some embedded compilers can not cope with this kind of assignment and do not report all violating cases. So I tend to put "CONST" if there is a future risk for this. (with a "#define CONST const" if possible).
            – le_top
            17 hours ago










          • @le_top: I guess you mean b=*c. This sounds like a compiler bug to me. What compiler had issues with this? I tried your code on avr-gcc, and it had no issues, even when I replaced const by __flash const, which has the effect of putting a in flash.
            – Edgar Bonet
            14 hours ago










          • Yes, b=*c. It will depend on the compiler and the uC. I file reports when I find bugs - when the compiler does not warn about it it is a bug, but otherwise it is a documented limitation.On Arduino you should use PROGMEM rather than __flash. I do not want to put a specific compilrer forward, my comment was mainly about warning that there are compilers for embedded systems that interpret const in a way that breaks code compatibility. That's also why you're required to add "__flash" to get the variable in FLASH - keeping it in RAM eases code generation (and speed) for those processors.
            – le_top
            12 mins ago














          1












          1








          1






          As explained in previous answers, fully parenthesizing the macros is the
          standard solution to this problem in C. However, on Arduino you are
          programming in C++, and in C++ it is considered good practice to replace
          this usage of #define by explicit constants:



          const int A = 200;
          const int B = A * 62;
          const int C = 500;


          Not only this makes the initial problem go away, it also provides some
          type safety: you can choose to give these constants other types (e.g.
          long) if appropriate.






          share|improve this answer












          As explained in previous answers, fully parenthesizing the macros is the
          standard solution to this problem in C. However, on Arduino you are
          programming in C++, and in C++ it is considered good practice to replace
          this usage of #define by explicit constants:



          const int A = 200;
          const int B = A * 62;
          const int C = 500;


          Not only this makes the initial problem go away, it also provides some
          type safety: you can choose to give these constants other types (e.g.
          long) if appropriate.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 2 days ago









          Edgar Bonet

          24k22344




          24k22344












          • Some compilers will interpret "const" as a variable going into program memory which then in turn results in issues with memory spaces. Consts offer type protection, which can also be (partially) achieved by casting inside the define "#define A ((int)200)" for instance.
            – le_top
            yesterday










          • @le_top: Do you have a specific example of the kind of “issues with memory spaces” you can get? I doubt you could find an example that does not invoke undefined behavior.
            – Edgar Bonet
            yesterday










          • Something along these lines for example: "const int a=100; int b=200; void setB(const int *c) {b=c;} void ex1() {setB(&a);}" . But there are other cases. When "const" puts "a" in ROM, some embedded compilers can not cope with this kind of assignment and do not report all violating cases. So I tend to put "CONST" if there is a future risk for this. (with a "#define CONST const" if possible).
            – le_top
            17 hours ago










          • @le_top: I guess you mean b=*c. This sounds like a compiler bug to me. What compiler had issues with this? I tried your code on avr-gcc, and it had no issues, even when I replaced const by __flash const, which has the effect of putting a in flash.
            – Edgar Bonet
            14 hours ago










          • Yes, b=*c. It will depend on the compiler and the uC. I file reports when I find bugs - when the compiler does not warn about it it is a bug, but otherwise it is a documented limitation.On Arduino you should use PROGMEM rather than __flash. I do not want to put a specific compilrer forward, my comment was mainly about warning that there are compilers for embedded systems that interpret const in a way that breaks code compatibility. That's also why you're required to add "__flash" to get the variable in FLASH - keeping it in RAM eases code generation (and speed) for those processors.
            – le_top
            12 mins ago


















          • Some compilers will interpret "const" as a variable going into program memory which then in turn results in issues with memory spaces. Consts offer type protection, which can also be (partially) achieved by casting inside the define "#define A ((int)200)" for instance.
            – le_top
            yesterday










          • @le_top: Do you have a specific example of the kind of “issues with memory spaces” you can get? I doubt you could find an example that does not invoke undefined behavior.
            – Edgar Bonet
            yesterday










          • Something along these lines for example: "const int a=100; int b=200; void setB(const int *c) {b=c;} void ex1() {setB(&a);}" . But there are other cases. When "const" puts "a" in ROM, some embedded compilers can not cope with this kind of assignment and do not report all violating cases. So I tend to put "CONST" if there is a future risk for this. (with a "#define CONST const" if possible).
            – le_top
            17 hours ago










          • @le_top: I guess you mean b=*c. This sounds like a compiler bug to me. What compiler had issues with this? I tried your code on avr-gcc, and it had no issues, even when I replaced const by __flash const, which has the effect of putting a in flash.
            – Edgar Bonet
            14 hours ago










          • Yes, b=*c. It will depend on the compiler and the uC. I file reports when I find bugs - when the compiler does not warn about it it is a bug, but otherwise it is a documented limitation.On Arduino you should use PROGMEM rather than __flash. I do not want to put a specific compilrer forward, my comment was mainly about warning that there are compilers for embedded systems that interpret const in a way that breaks code compatibility. That's also why you're required to add "__flash" to get the variable in FLASH - keeping it in RAM eases code generation (and speed) for those processors.
            – le_top
            12 mins ago
















          Some compilers will interpret "const" as a variable going into program memory which then in turn results in issues with memory spaces. Consts offer type protection, which can also be (partially) achieved by casting inside the define "#define A ((int)200)" for instance.
          – le_top
          yesterday




          Some compilers will interpret "const" as a variable going into program memory which then in turn results in issues with memory spaces. Consts offer type protection, which can also be (partially) achieved by casting inside the define "#define A ((int)200)" for instance.
          – le_top
          yesterday












          @le_top: Do you have a specific example of the kind of “issues with memory spaces” you can get? I doubt you could find an example that does not invoke undefined behavior.
          – Edgar Bonet
          yesterday




          @le_top: Do you have a specific example of the kind of “issues with memory spaces” you can get? I doubt you could find an example that does not invoke undefined behavior.
          – Edgar Bonet
          yesterday












          Something along these lines for example: "const int a=100; int b=200; void setB(const int *c) {b=c;} void ex1() {setB(&a);}" . But there are other cases. When "const" puts "a" in ROM, some embedded compilers can not cope with this kind of assignment and do not report all violating cases. So I tend to put "CONST" if there is a future risk for this. (with a "#define CONST const" if possible).
          – le_top
          17 hours ago




          Something along these lines for example: "const int a=100; int b=200; void setB(const int *c) {b=c;} void ex1() {setB(&a);}" . But there are other cases. When "const" puts "a" in ROM, some embedded compilers can not cope with this kind of assignment and do not report all violating cases. So I tend to put "CONST" if there is a future risk for this. (with a "#define CONST const" if possible).
          – le_top
          17 hours ago












          @le_top: I guess you mean b=*c. This sounds like a compiler bug to me. What compiler had issues with this? I tried your code on avr-gcc, and it had no issues, even when I replaced const by __flash const, which has the effect of putting a in flash.
          – Edgar Bonet
          14 hours ago




          @le_top: I guess you mean b=*c. This sounds like a compiler bug to me. What compiler had issues with this? I tried your code on avr-gcc, and it had no issues, even when I replaced const by __flash const, which has the effect of putting a in flash.
          – Edgar Bonet
          14 hours ago












          Yes, b=*c. It will depend on the compiler and the uC. I file reports when I find bugs - when the compiler does not warn about it it is a bug, but otherwise it is a documented limitation.On Arduino you should use PROGMEM rather than __flash. I do not want to put a specific compilrer forward, my comment was mainly about warning that there are compilers for embedded systems that interpret const in a way that breaks code compatibility. That's also why you're required to add "__flash" to get the variable in FLASH - keeping it in RAM eases code generation (and speed) for those processors.
          – le_top
          12 mins ago




          Yes, b=*c. It will depend on the compiler and the uC. I file reports when I find bugs - when the compiler does not warn about it it is a bug, but otherwise it is a documented limitation.On Arduino you should use PROGMEM rather than __flash. I do not want to put a specific compilrer forward, my comment was mainly about warning that there are compilers for embedded systems that interpret const in a way that breaks code compatibility. That's also why you're required to add "__flash" to get the variable in FLASH - keeping it in RAM eases code generation (and speed) for those processors.
          – le_top
          12 mins ago


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Arduino 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.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • 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%2farduino.stackexchange.com%2fquestions%2f60097%2farduino-incorrect-calculation-of-long-integer%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

          "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

          Alcedinidae

          Origin of the phrase “under your belt”?