3

Just looking for an answer to a question no amount of googling appears to resolve.

if..

a = 1.23

I would like to be able to take the 1 and multiply this number yet keep the .23

How is this possible??

Thanks in advance!

Adam Spaniels
  • 33
  • 1
  • 1
  • 3
  • 1
    Why do you call this operation "indexing"? It sounds like you're thinking in terms of selecting and operating on parts of the string representation of the number. If so, you'll want to stop thinking of numbers in terms of text and start thinking about numeric operations. Here, it looks like you want to round down or round toward zero. – user2357112 Sep 18 '14 at 17:49
  • possible duplicate of [splitting a number into the integer and decimal parts in python](http://stackoverflow.com/questions/6681743/splitting-a-number-into-the-integer-and-decimal-parts-in-python) – munk Sep 18 '14 at 17:53
  • You actual problem is very [hard to detect](http://stackoverflow.com/questions/25919129/how-do-you-index-a-float-value-in-python/25958114#comment40573206_25919190). – Wolf Sep 21 '14 at 10:16

5 Answers5

2

In the comments to munkhd's answer you said:

I have want to be able to input a value as hours then convert them to minutes. So if it was 1.20 I would multiply the 1 by 60 then add 20. Im sure there must be an easier method :)

Thus your program will receive 1.20 as a string. So you can use string methods on it, eg

>>> dotted_time = '1.20'
>>> h, m = [int(s) for s in dotted_time.split('.')]
>>> print h, m
1 20
>>> minutes = 60*h + m
>>> hours = minutes / 60.0
>>> print minutes, hours
80 1.33333333333

Alternatively, you can do colon_time = dotted_time.replace('.', ':'); colon_time is in a format that the standard time functions can understand and manipulate for you. This is probably the more sensible way to proceed, and it will easily cope if you want to process times with seconds like '1.20.30' which .replace('.', ':') will convert to '1:20:30'.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
1

Besides PM 2Ring's answer seems to solve [1] your actual problem, you may "index floats", of course after converting it to strings, but be aware of the limited accuracy. So use the built-in round function to define the accuracy required by your solution:

s = str(round(a, 2)) # round a to two digits

Now, you may apply all the string functions you want to it. After that you probably need to convert your results back to float or int ...


[1] Others already suggested this: when dealing with common models like time in a high-level language like python, expect to be supported by reliable solutions that are already there.

Community
  • 1
  • 1
Wolf
  • 9,679
  • 7
  • 62
  • 108
0

Is int() what you're looking for:

In [39]: a = 1.23

In [40]: int(a)
Out[40]: 1

In [41]: a
Out[41]: 1.23
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • `>>> a-int(a) 0.22999999999999998` , it does round off to 0.23 – g4ur4v Sep 18 '14 at 17:47
  • I think he wants something more like (somefloat.integerpart * N + somefloat.fractionalpart). Ex. 1.23 becomes 6.23 when you fake-multiply by 6. – Kevin Sep 18 '14 at 17:48
0

You can't index a float as such. It's not a collection. For more info on how floating point numbers work, read http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

The math library gives you a way to get a tuple with the two parts of the number though

>>> import math
>>> a = 1.23
>>> math.modf(a)
(0.22999999999999998, 1.0)

This is not exacct because of the way floating point numbers are represented, but the value is on the order of 1e-17.

Of course, this is always possible too...

>>> map(int, str(a).split('.'))
[1, 23]
munk
  • 12,340
  • 8
  • 51
  • 71
  • This looks like what it is I am looking for. To explain exactly what is I am doing. I have want to be able to input a value as hours then convert them to minutes. So if it was 1.20 I would multiply the 1 by 60 then add 20. Im sure there must be an easier method :) Sorry about the formatting, this is only my second question and am trying to get to grips with the site. – Adam Spaniels Sep 18 '14 at 18:00
  • 4
    If you're working with time, you should *definitely* be using the time module and not trying to coerce a float into a weird time representation. – munk Sep 18 '14 at 18:20
  • 1
    If you are looking to to time arithmatic you should use timedelta objects which are designed for this. 'import datetime as dt; dt.timedelta(hours=1, minutes=20).seconds // 60` – b10n Sep 18 '14 at 18:21
0

modf() and round()

Use modf() to get the whole number and fractional part. modf() will return a tuple of (fractional, whole). Use round() to account for how precise you want the answer.

>>> import math
>>> a = 1.23
>>> math.modf(a) (0.22999999999999998, 1.0)
>>> math.modf(a)[0] #the zeroth location of the tuple is the fractional part
0.22999999999999998 # some precision lost, use round() to fix
>>> round(math.modf(a)[0], 2)
0.23 # This is an exact match the source fractional part

Further, if you want to index each specific portion of the float you can use this:

def get_pos_float(num, unit, precision=3):
    if unit >= 10:
        num = abs(round(math.modf(num)[0], 3)) # Get just the fractional part
        num *= 10 # Move the decimal point one place to the right
        return get_pos_float(num, unit/10)
    retVal = int(math.modf(num)[1]) #Return the whole number part
    return retVal

It is used as follows:

>>> get_pos_float(1.23, 10)
2
>>> get_pos_float(1.23, 100)
3
rouble
  • 16,364
  • 16
  • 107
  • 102