3

I'm trying to round numbers derived from cmath's divide function to a "whole" number, the results often being negative due to the nature of the program.

Example code:

strength = input("Input Strength Stat: ")
str_mod = round(strength/2)

However, the result of this is that it, due to an oddity in python, always returns closer to zero rather than further if, say str_mod prior to rounding ends up at something like -1.5 (resulting in -1 rather than -2 as desired)

This, since I'm trying to create an automatic derived stat calc script for a custom Pen and Paper RPG system, is not the desired behavior. What I desire is for the script to return, at -1.5, -2.0 upon rounding. I need to be able to do this while still rounding positive numbers up similarly.

martineau
  • 119,623
  • 25
  • 170
  • 301
user1524705
  • 63
  • 1
  • 5

5 Answers5

4

this is because you are getting a(truncated) int from strength/2

try strength/2.0

this is not an oddity with python but simply how most languages cast types for numbers

5/2 = 2

5/2.0 = 2.5

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • 1
    or `from __future__ import division` – mgilson Jul 13 '12 at 22:03
  • 1
    yeah ... but still its better he understands some bit of numeric casting for any other language he might deal with – Joran Beasley Jul 13 '12 at 22:04
  • (+1) Nice work figuring out what the actual problem was. Sometimes these problems with `input` are a little difficult because of the type differences between python2 and python3. You nailed this one pretty fast though. – mgilson Jul 13 '12 at 22:17
  • This was ultimately the best answer, but unfortunately less useful than the one just under it that points out a major security flaw in my program, and how to fix it. Thank you. – user1524705 Jul 14 '12 at 23:57
3

You could do this the safe way:

strength = float(raw_input("Input Strength Stat:"))
str_mod = round(strength/2)

In this case, since strength is guaranteed to be a float, you can safely divide by 2 without worrying about truncation or importing division from __future__. As a bonus, you remove a huge security liability in your game as well.

Using input, a user could do some serious damage to your system:

RPG console> Input Strength Stat: __import__('os').system('rm -r ~')
                                 #^ User input (don't try this!)
mgilson
  • 300,191
  • 65
  • 633
  • 696
0

You may need to use Decimal to get the same rounding as RPG. With Decimal, you can set the rounding mode to up, down, half up, etc.

Community
  • 1
  • 1
dawg
  • 98,345
  • 23
  • 131
  • 206
0

Alternatively, you could try:

from __future__ import division

in order to use py3k division. (e.g. result will be always float)

jermenkoo
  • 643
  • 5
  • 20
0

If I understand your problem right, you'd like something that will round half away from zero, as:

-0.5 -> -1

0.5 -> 1

These folks have some good answers. In particular, I based my answer below on AGN Gazer's answer:

from math import floor, ceil

strength = float(raw_input("Input Strength Stat:"))
str_mod  = floor((strength/2) + 0.5) if strength  >= 0.0 else ceil((strength/2)  - 0.5)

Thanks AGN Gazer!

Marcus Bean
  • 441
  • 4
  • 7