0

The mod operation with negative numbers was not working as expected. I was trying to get the floating part of a number, and I used num % 1 to get it, was working, until it was negative, when was negative it worked in a strange way, only while running, when I tested it on the terminal, worked as expected with both signs (+ or -), but when was into the program it worked wrong, I saw someone talking about being an integer, and recommended using num % 1.0, but didn't worked, I got the same problem either way.

The time_difference_minutes % 1 isn't working properly, it's returning 0.7142857142857126 But it was supposed to return 0.285714285714287 (float part)


The strange part was, when i did it directly in the prompt, it worked, than I did again just this snippet on a new file print(4.285714285714287 % 1) And worked, I got the expected, but once I added the "-" signal, it started happening again, but the output was the same every time, I noticed it everytime goes wrong, and I didn't found any explanation about this in specific, other point I noticed was it works on terminal with the "-" signal, just when the program was running it returned wrong.


I used the abs() to solve the problem, but I really want to understand what's going wrong here.


Code example:

# Constants
AVENUE_LENGTH_KM = 22.5
OLD_SPEED_KMH = 70
NEW_SPEED_KMH = 90

# Calculations
time_taken_old_speed_hours = AVENUE_LENGTH_KM / OLD_SPEED_KMH
time_taken_new_speed_hours = AVENUE_LENGTH_KM / NEW_SPEED_KMH

time_difference_hours = time_taken_new_speed_hours - time_taken_old_speed_hours
time_difference_minutes = time_difference_hours * 60
time_difference_seconds = time_difference_minutes * 60

# Output
print("{:.2f} hours".format(time_difference_hours))
print("{:.0f} minutes and {:.0f} seconds".format(
    time_difference_minutes, (time_difference_minutes % 1) * 60))
print("{:.0f} seconds".format(time_difference_seconds))
AlephZHR0
  • 1
  • 1
  • Aside: In C, `%` and `fmod()` are the _remainder_, not the _modulo_. [Difference](https://stackoverflow.com/a/20638659/2410359) – chux - Reinstate Monica Jun 13 '23 at 04:41
  • I wrote wrong, thanks for the correction! – AlephZHR0 Jun 13 '23 at 04:45
  • To be clear, does you `time_difference_minutes` have a value of about -4.28571? ... So all you are asking is why `-4.285714285714287 % 1` is 0.7142857142857126 and not 0.285714285714287 or -0.285714285714287? – chux - Reinstate Monica Jun 13 '23 at 14:33
  • I thought using %1 should just give me the decimal part of numbers, because it would divide fully the integer part. It worked fine when I tried it on Terminal. But when I used it in the program (x % 1), I got results that didn't make sense to me. – AlephZHR0 Jun 15 '23 at 18:51

1 Answers1

0

Python always maintains the relationship: a//b * b + a%b == a. Since the floor division rounds down for a negative number, the modulus adjusts to compensate.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622