Skip to content

Commit

Permalink
Fixed the modulo operator for negative integers
Browse files Browse the repository at this point in the history
* this changes the behavior of vanilla modulo operator to use signed
integer division to match how the fixed division operator works.
  • Loading branch information
NovaRain committed Jan 25, 2024
1 parent 4f786f3 commit b8fe8cb
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions sfall/Modules/BugFixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3305,13 +3305,16 @@ void BugFixes::init() {
SafeWriteBatch<WORD>(0x04DB, { // fild 64bit > fild 32bit
0x46A3A8, 0x46A3F4, // op_mul_
0x46A4E7, 0x46A566, // op_div_
0x46A280, 0x46A2CD, // op_sub_
0x46A280, 0x46A2CD // op_sub_
});

// Fix for vanilla division operator treating negative integers as unsigned
// Fix for vanilla division and modulo operators treating negative integers as unsigned
//if (IniReader::GetConfigInt("Misc", "DivisionOperatorFix", 1)) {
dlogr("Applying division operator fix.", DL_FIX);
SafeWrite32(0x46A51D, 0xFBF79990); // xor edx, edx; div ebx > cdq; idiv ebx
SafeWriteBatch<DWORD>(0x90FBF799, { // xor edx, edx; div ebx > cdq; idiv ebx
0x46A51D, // op_div_
0x46A669 // op_mod_
});
//}

//if (IniReader::GetConfigInt("Misc", "SpecialUnarmedAttacksFix", 1)) {
Expand Down

1 comment on commit b8fe8cb

@NovaRain
Copy link
Collaborator Author

@NovaRain NovaRain commented on b8fe8cb Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda forgot the modulo when we fixed the division operator in 4.2.3.
Test script code:

variable i;
for (i := -5; i <= 5; i++) begin
   display_msg("Div/Mod test pos: " + i + ", div: " + (i / 3) + ", mod: " + (i % 3));
   display_msg("Div/Mod test neg: " + i + ", div: " + (i / -3) + ", mod: " + (i % -3));
end

Results:

// before                                // now
Div/Mod test pos: -5, div: -1, mod: 2    Div/Mod test pos: -5, div: -1, mod: -2
Div/Mod test neg: -5, div: 1, mod: -5    Div/Mod test neg: -5, div: 1, mod: -2
Div/Mod test pos: -4, div: -1, mod: 0    Div/Mod test pos: -4, div: -1, mod: -1
Div/Mod test neg: -4, div: 1, mod: -4    Div/Mod test neg: -4, div: 1, mod: -1
Div/Mod test pos: -3, div: -1, mod: 1    Div/Mod test pos: -3, div: -1, mod: 0
Div/Mod test neg: -3, div: 1, mod: 0     Div/Mod test neg: -3, div: 1, mod: 0
Div/Mod test pos: -2, div: 0, mod: 2     Div/Mod test pos: -2, div: 0, mod: -2
Div/Mod test neg: -2, div: 0, mod: 1     Div/Mod test neg: -2, div: 0, mod: -2
Div/Mod test pos: -1, div: 0, mod: 0     Div/Mod test pos: -1, div: 0, mod: -1
Div/Mod test neg: -1, div: 0, mod: 2     Div/Mod test neg: -1, div: 0, mod: -1
Div/Mod test pos: 0, div: 0, mod: 0      Div/Mod test pos: 0, div: 0, mod: 0
Div/Mod test neg: 0, div: 0, mod: 0      Div/Mod test neg: 0, div: 0, mod: 0
Div/Mod test pos: 1, div: 0, mod: 1      Div/Mod test pos: 1, div: 0, mod: 1
Div/Mod test neg: 1, div: 0, mod: 1      Div/Mod test neg: 1, div: 0, mod: 1
Div/Mod test pos: 2, div: 0, mod: 2      Div/Mod test pos: 2, div: 0, mod: 2
Div/Mod test neg: 2, div: 0, mod: 2      Div/Mod test neg: 2, div: 0, mod: 2
Div/Mod test pos: 3, div: 1, mod: 0      Div/Mod test pos: 3, div: 1, mod: 0
Div/Mod test neg: 3, div: -1, mod: 3     Div/Mod test neg: 3, div: -1, mod: 0
Div/Mod test pos: 4, div: 1, mod: 1      Div/Mod test pos: 4, div: 1, mod: 1
Div/Mod test neg: 4, div: -1, mod: 4     Div/Mod test neg: 4, div: -1, mod: 1
Div/Mod test pos: 5, div: 1, mod: 2      Div/Mod test pos: 5, div: 1, mod: 2
Div/Mod test neg: 5, div: -1, mod: 5     Div/Mod test neg: 5, div: -1, mod: 2

At least now they match the results from MSVC.

Please sign in to comment.