-
July 10th, 2024, 02:04 PM
#1
Help needed in conversion
Hello,
Its been a while here now. But I had lot of help earlier.
Im facing one issue in conversion:
In the current code,
Code:
long Xmin = -228725;
long Ymax = 10023525;
unsigned long uiRes = 50;
long iXOffset = Xmin % uiRes;
iXOffset is coming as 21.
But if i change to
Code:
long Xmin = -228725;
long Ymax = 10023525;
int uiRes = 50;
long iXOffset = Xmin % uiRes;
Or
long iXOffset = Xmin % 50;
it is coming correctly as 25
Why is the current declaration of "unsigned long " causing the issue ? Please help urgently
thankyou very much
~p
-
July 11th, 2024, 12:22 AM
#2
Re: Help needed in conversion
To quote C99
4 The result of the binary * operator is the product of the operands.
5 The result of the / operator is the quotient from the division of the first operand by the
second; the result of the % operator is the remainder. In both operations, if the value of
the second operand is zero, the behavior is undefined.
6 When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded.78) If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a.
Note the underlined word.
You're also mixing signed and unsigned arithmetic, which is also poorly defined in C.
> it is coming correctly as 25
Weird, I get different answers.
Code:
$ cat foo.c
#include <stdio.h>
void foo ( ) {
long Xmin = -228725;
unsigned long uiRes = 50;
long iXOffset = Xmin % uiRes;
printf("In foo: iXOffset=%ld\n", iXOffset);
printf("Check: %ld == %ld\n", Xmin, (Xmin/uiRes)*uiRes + Xmin%uiRes );
}
void bar ( ) {
long Xmin = -228725;
int uiRes = 50;
long iXOffset = Xmin % uiRes;
printf("In bar: iXOffset=%ld\n", iXOffset);
printf("Check: %ld == %ld\n", Xmin, (Xmin/uiRes)*uiRes + Xmin%uiRes );
}
int main ( ) {
foo();
bar();
}
$ ./a.out
In foo: iXOffset=41
Check: -228725 == -228725
In bar: iXOffset=-25
Check: -228725 == -228725
Both are correct, because the identity "(a/b)*b + a%b shall equal a." holds.
If you're really looking for modulo, then % is the wrong thing to be using if negative values are involved.
https://stackoverflow.com/questions/...gative-numbers
https://en.wikipedia.org/wiki/Modulo...ming_languages
-
July 11th, 2024, 01:38 AM
#3
Re: Help needed in conversion
Thankyou so much for help. (with the details and examples ). Really helped me a lot. and its not easy to convince legacy people without proper documentation, as Im relatively new and this is legacy code, blowing up at negetive values.
-
July 11th, 2024, 03:48 AM
#4
Re: Help needed in conversion
Using VS2022 I get the same result as pdk5:
Code:
In foo: iXOffset=21
Check: -228725 == -228725
In bar: iXOffset=-25
Check: -228725 == -228725
PS. Note that when signed and unsigned are mixed, if possible signed is 'promoted' to unsigned. Thus signed -228725 if 'promoted' to unsigned becomes 4294738571 and 4294738571 % 50 is 21. When the divisor and dividend are both of the same sign type then no promotion is applied and mod is Xmin - (Xmin / uiRes) * uiRes) which gives 21 for 4294738571 and -25 for -228725. Note that if uiRes is -50 (ie signed), then the mod result is still -25 (you can't have an unsigned value of -50!).
Don't mix signed and unsigned - it will bite at some point and bite hard.
Last edited by 2kaud; July 11th, 2024 at 07:42 AM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
July 11th, 2024, 08:54 AM
#5
Re: Help needed in conversion
Thankyou very much kaud, again !!! .. Again great explanation for what is causing the new value..
-
July 11th, 2024, 10:47 AM
#6
Re: Help needed in conversion
Try this simple program:
Code:
#include <iostream>
int main() {
const auto x {-4 + 2u};
std::cout << x << '\n';
}
What is the type of x and what is displayed?
https://godbolt.org/z/9c14YEfPv
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|