473,770 Members | 2,082 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

is int(round(val)) safe?

I realize this probably a stupid question, but...is it safe to
round to the nearest integer by using int(round(val)) ?

I suspect it is fine, but wanted to be sure that weird floating point
representation on some platform might make it unsafe there (i.e. get the
wrong value due to the floating point value being an approximation) and
if so, is there a Better Way).

-- Russell
Jul 18 '05 #1
11 2530
Russell E. Owen wrote:
I realize this probably a stupid question, but...is it safe to
round to the nearest integer by using int(round(val)) ?
Define "safe".
I suspect it is fine, but wanted to be sure that weird floating point
representation on some platform might make it unsafe there (i.e. get the
wrong value due to the floating point value being an approximation) and
if so, is there a Better Way).


Since round() returns an integer, and since (ignoring really
large integers, since I doubt you're concerned about them
here) floating point values can handle *integer* values
perfectly well, there's no reason it shouldn't do what you
want.

The problem* with floating point is inaccurate representation
of certain _fractional_ values, not integer values.

-Peter

* Well, _one_ of the problems. ;-)
Jul 18 '05 #2
Peter Hansen wrote:
Since round() returns an integer


Just to clarify in case anyone else misreads this, I belive the intent
here was to say that round(f) -- that is, round with only a single
argument -- returns a floating point number with no fractional component
after the decimal point. The result is still a float, not an int though:
round(3.1415926 5359) 3.0 round(3.1415926 5359, 2)

3.1400000000000 001

I think the intent was clear from the rest of the post, but I figured it
wouldn't hurt to clarify this for any newbies who misread it like I did.

Steve
Jul 18 '05 #3
Steven Bethard wrote:
Peter Hansen wrote:
Since round() returns an integer


Just to clarify in case anyone else misreads this, I belive the intent
here was to say that round(f) -- that is, round with only a single
argument -- returns a floating point number with no fractional component
after the decimal point. The result is still a float, not an int though:
>>> round(3.1415926 5359) 3.0 >>> round(3.1415926 5359, 2)

3.1400000000000 001

I think the intent was clear from the rest of the post, but I figured it
wouldn't hurt to clarify this for any newbies who misread it like I did.


All true.

I wonder if it would be appropriate to say something along
the lines of '''round() returns an integer, but not an "int".'''

Obviously the mathematicians will have something to say about
this. In computers, 1.0 may not be an integer data type, but
I think in math it's still considered an integer. I am most
definitely not going to claim authority in this area, however,
since as an engineer I consider 1.0 and 1 merely "equal to a
first approximation". <wink>

-Peter
Jul 18 '05 #4
[Peter Hansen]
....
I wonder if it would be appropriate to say something along
the lines of '''round() returns an integer, but not an "int".'''
Well, round() is a 2-argument function, whose second argument defaults
to 0. It's quite defensible to say that round returns an integer
value when the second argument is 0.
Obviously the mathematicians will have something to say about
this. In computers, 1.0 may not be an integer data type, but
I think in math it's still considered an integer.
Depends on which mathematician you're talking to. The integer 1 is
most often defined as the set containing the empty set, or, in a
suitably restricted set theory, with the set of all sets containing 1
element (which is a proper class in most set theories). A real, OTOH,
is a godawful construction that Americans typically don't learn until
after they've completed "calculus" and gone on to "analysis".

So, instead of talking to mathematicians, I advise talking to me
<wink>. Yes, 1.0 is an integer! In fact, so is 1.9998e143: all
sufficient large floats are exact integers. That's why, e.g.,
math.ceil() and math.floor() return arguments like 1.9998e143
unchanged -- such inputs are already integers.
I am most definitely not going to claim authority in this area, however,
since as an engineer I consider 1.0 and 1 merely "equal to a
first approximation". <wink>


If they differ at all, then e = 1.0 - 1 must be nonzero. Since it
isn't, they're identical <wink>.
Jul 18 '05 #5
On Mon, 22 Nov 2004 15:58:54 -0500, Peter Hansen <pe***@engcorp. com> wrote:
Russell E. Owen wrote:
I realize this probably a stupid question, but...is it safe to
round to the nearest integer by using int(round(val)) ?
Define "safe".
I suspect it is fine, but wanted to be sure that weird floating point
representation on some platform might make it unsafe there (i.e. get the
wrong value due to the floating point value being an approximation) and
if so, is there a Better Way).


Since round() returns an integer, and since (ignoring really
large integers, since I doubt you're concerned about them
here) floating point values can handle *integer* values
perfectly well, there's no reason it shouldn't do what you
want.

The problem* with floating point is inaccurate representation
of certain _fractional_ values, not integer values.


Well, you mentioned really large integers, and I think it's worth
mentioning that you can get inaccurate representation of certain of those
values too. I.e., what you really have (for ieee 754 doubles) is 53 bits
to count with in steps of one weighted unit, and the unit can be 2**0
or 2**otherpower, where otherpower has 11 bits to represent it, more or less
+- 2**10 with an offset for 53. If the unit step is 2**1, you get twice the range
of integers, counting by two's, which doesn't give you a way of representing the
odd numbers between accurately. So it's not only fractional values that can get
truncated on the right. Try adding 1.0 to 2.0**53 ;-)
2.0**53 900719925474099 2.0 2 **53 # just to check 900719925474099 2L 2.0**53 + 1.0 900719925474099 2.0 2 **53 + 1 # just to check 900719925474099 3L

The float gets rounded down, but you can count by two's
2.0**53 900719925474099 2.0 2.0**53 +2.0

900719925474099 4.0

(2.0**53-1.0 is the last number with a LSB value of 1.0, but you can add 1.0
to that and get an exact 2.0**53 because the unit bit that results is 0 so it
doesn't matter that it's to the right of the new LSB of 2.0**53 (which has a weight of 2.0)).

Another way of thinking about it is that it's not about the accuracy of the numbers,
it's about how far apart the available accurate number representations are and the
choice you have to make if the value you want to represent falls between.

-Peter

* Well, _one_ of the problems. ;-)


Regards,
Bengt Richter
Jul 18 '05 #6
"Russell E. Owen" <ro***@cesmail. net> wrote in message news:<ro******* *************** ***@gnus01.u.wa shington.edu>.. .
I realize this probably a stupid question, but...is it safe to
round to the nearest integer by using int(round(val)) ?

I suspect it is fine, but wanted to be sure that weird floating point
representation on some platform might make it unsafe there (i.e. get the
wrong value due to the floating point value being an approximation) and
if so, is there a Better Way).


Yes, int(round(val)) is safe. The only concern is avoiding errors in
"val" itself. For example,
val 3.4999999999999 996 # Should have been exactly 3.5 int(round(val))

3 # Should have been 4
Jul 18 '05 #7
Tim Peters wrote:
[Peter Hansen]
....
I wonder if it would be appropriate to say something along
the lines of '''round() returns an integer, but not an "int".'''

Well, round() is a 2-argument function, whose second argument defaults
to 0. It's quite defensible to say that round returns an integer
value when the second argument is 0.

Obviously the mathematicians will have something to say about
this. In computers, 1.0 may not be an integer data type, but
I think in math it's still considered an integer.

Depends on which mathematician you're talking to. The integer 1 is
most often defined as the set containing the empty set, or, in a
suitably restricted set theory, with the set of all sets containing 1
element (which is a proper class in most set theories). A real, OTOH,
is a godawful construction that Americans typically don't learn until
after they've completed "calculus" and gone on to "analysis".

And most of them don't understand even then. What I want to know is why
doesn't Python 2.4 have a speedy implementation of infinite-dimensional
Banach spaces?
So, instead of talking to mathematicians, I advise talking to me
<wink>. Yes, 1.0 is an integer! In fact, so is 1.9998e143: all
sufficient large floats are exact integers. That's why, e.g.,
math.ceil() and math.floor() return arguments like 1.9998e143
unchanged -- such inputs are already integers.

I am most definitely not going to claim authority in this area, however,
since as an engineer I consider 1.0 and 1 merely "equal to a
first approximation". <wink>

If they differ at all, then e = 1.0 - 1 must be nonzero. Since it
isn't, they're identical <wink>.


You can tell this by examining the behavior of something as simple (;-)
as a Python dict:
d = {1.0: "Something" , .... 1: "Something else"} d {1.0: 'Something else'}


Python has known for a long time that 1.0 and 1 are the same thing.
Note, however, that I don't believe it's guaranteed that the contents of
d will turn out the same in different Python versions. I suppose Tim
would be able to quote chapter and verse, given his familiarity with
every little implementation detail of the dict.

guaranteed-to-confuse-the-confusable-ly y'rs - steve
--
http://www.holdenweb.com
http://pydish.holdenweb.com
Holden Web LLC +1 800 494 3119
Jul 18 '05 #8
bo**@oz.net (Bengt Richter) writes:
On Mon, 22 Nov 2004 15:58:54 -0500, Peter Hansen <pe***@engcorp. com> wrote:
Russell E. Owen wrote:
The problem* with floating point is inaccurate representation
of certain _fractional_ values, not integer values.


Well, you mentioned really large integers, and I think it's worth
mentioning that you can get inaccurate representation of certain of those
values too. I.e., what you really have (for ieee 754 doubles) is 53 bits
to count with in steps of one weighted unit, and the unit can be 2**0
or 2**otherpower, where otherpower has 11 bits to represent it, more or less
+- 2**10 with an offset for 53. If the unit step is 2**1, you get twice the range
of integers, counting by two's, which doesn't give you a way of representing the
odd numbers between accurately. So it's not only fractional values that can get
truncated on the right. Try adding 1.0 to 2.0**53 ;-)


It's much easier than that to get integer floating point numbers that
aren't correct. Consider:
long(1e70)

100000000000000 007253143638152 923512615837440 964652195551821 01554790400L

I don't know the details on 754 FP, but the FP I'm used to represents
*all* numbers as a binary fraction times an exponent. Since .1 can't
be represented exactly, 1e<anything> will be wrong if you ask for
enough digits.

This recently caused someone to propose that 1e70 should be a long
instead of a float. No one mentioned the idea of making

[0-9]+[eE]+?[0-9]+ be of integer type, and

[0-9]*.[0-9]+[eE][+-]?[0-9]+ be a float. [0-9]+[eE]-[0-9]+ would also
be a float. No simple rule for this, unfortunately.

<mike

--
Mike Meyer <mw*@mired.or g> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jul 18 '05 #9
On Tue, 23 Nov 2004 10:50:23 -0600, Mike Meyer <mw*@mired.or g> wrote:
bo**@oz.net (Bengt Richter) writes:
On Mon, 22 Nov 2004 15:58:54 -0500, Peter Hansen <pe***@engcorp. com> wrote:
Russell E. Owen wrote:
The problem* with floating point is inaccurate representation
of certain _fractional_ values, not integer values.
Well, you mentioned really large integers, and I think it's worth
mentioning that you can get inaccurate representation of certain of those
values too. I.e., what you really have (for ieee 754 doubles) is 53 bits
to count with in steps of one weighted unit, and the unit can be 2**0
or 2**otherpower, where otherpower has 11 bits to represent it, more or less
+- 2**10 with an offset for 53. If the unit step is 2**1, you get twice the range
of integers, counting by two's, which doesn't give you a way of representing the
odd numbers between accurately. So it's not only fractional values that can get
truncated on the right. Try adding 1.0 to 2.0**53 ;-)


It's much easier than that to get integer floating point numbers that
aren't correct. Consider:
long(1e70)10000000000000 000725314363815 292351261583744 096465219555182 101554790400L


Yes. I was just trying to identify the exact point where you lose 1.0 granularity.
The last number, with all ones in the available significant bits (including the hidden one)
is 2.**53-1.0
from ut.miscutil import prb
prb(2.**53-1.0) '11111111111111 111111111111111 111111111111111 111111111' prb(2.**53-1.0).count('1') 53

the last power of 10 that is accurate is 22, and the reason is plain
when you look at the bits:

10**22 has more than 53 bits but only zeroes to the right of the 53, but 10**23
has a bit to the right.
prb(2.**53-1.0) '11111111111111 111111111111111 111111111111111 111111111' prb(10**22) '10000111100001 100111100000110 010011011101010 110010010000000 000000000000000 ' prb(1e22) '10000111100001 100111100000110 010011011101010 110010010000000 000000000000000 '

whereas for 23 1e23 != 10**23 prb(10**23) '10101001011010 000001011000111 111000010100101 011110110100000 000000000000000 000' prb(1e23) '10101001011010 000001011000111 111000010100101 011110110000000 000000000000000 000'

The zeroes are eliminated if you use a power of 10/2 or 5, which is always odd prb( 5**22) '10000111100001 100111100000110 010011011101010 11001001' prb( 5**23) '10101001011010 000001011000111 111000010100101 0111101101' prb(2.**53-1.0) '11111111111111 111111111111111 111111111111111 111111111'

Or in decimal terms:
5.**22 238418579101562 5.0 5**22 238418579101562 5L 5.**23 119209289550781 24.0 5**23 119209289550781 25L 2**53 900719925474099 2L

so what makes 5.**22 ok is that
5.**22 <= 2.**53-1 True
I don't know the details on 754 FP, but the FP I'm used to represents
*all* numbers as a binary fraction times an exponent. Since .1 can't
be represented exactly, 1e<anything> will be wrong if you ask for
enough digits. I don't understand the "since .1 ..." logic, but I agree with the second
part. Re *all* numbers, if you multiply the fraction represented by the
53 fractional bits of any number by 2**53 you get an integer that you can
consider to be multiplied by 2 ** (the exponent for the fraction - 53),
which doesn't change anything, so I did that, so I could talk about
counting by increments of 1 unit of least precision. But yes, the
usual description is as a fraction times a power of two.

This recently caused someone to propose that 1e70 should be a long
instead of a float. No one mentioned the idea of making

[0-9]+[eE]+?[0-9]+ be of integer type, and

[0-9]*.[0-9]+[eE][+-]?[0-9]+ be a float. [0-9]+[eE]-[0-9]+ would also
be a float. No simple rule for this, unfortunately.

I wrote a little exact decimal module based on keeping decimal exponents and
a rational numerator/denominator pair, which allows keeping an exact representation
of any reasonable (that you might feel like typing ;-) literal, like 1e70, etc., e.g.,
ED('1e70') ED('1.0e70') ED('1e70').astu ple() (1, 1, 70) ED('1.23e-45') ED('1.23e-45') ED('1.23e-45').astuple() (123, 1, -47) ED('0.1') ED('0.1') ED('0.1').astup le() (1, 1, -1)
The reason I mention this is not because I think all floating constants should be represented
this way in final code, but that maybe they should in the compiler ast, before code has been
generated. At that point, it seems a shame to have done a premature lossy conversion to platform
floating point, since one might want to take the AST and generate code with other representations .
I.e.,
import compiler
compiler.parse( 'a=0.1') Module(None, Stmt([Assign([AssName('a', 'OP_ASSIGN')], Const(0.1000000 0000000001))])) compiler.parse( '0.1') Module(None, Stmt([Discard(Const(0 .10000000000000 001))]))

but from ut.exactdec import ED
ED('0.1') ED('0.1') ED('0.1').astup le() (1, 1, -1)

vs what's represented by the actual floating point bits
ED(0.1,'all') ED('0.100000000 000000005551115 123125782702118 158340454101562 5') ED(0.1,'all').a stuple()

(10000000000000 000555111512312 578270211815834 04541015625L, 1L, -55)

Anyway, tuple is an easy exact possibility for intermediate representation of the number.
Of course, I guess you'd have to tag it as being from a floating point literal or else a code
generator would lose that implicit representation directive for ordinary code generation ...

Regards,
Bengt Richter
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
4118
by: Jody Gelowitz | last post by:
I am trying to find the definition of "Safe Printing" and cannot find out exactly what this entitles. The reason is that I am trying to print contents from a single textbox to no avail using the PrintDialog control under a security setting with only SafePrinting allowed. I have attached a sample project that I am using to try to accomplish this. The print dialog appears, but when I press the Print button, I get an exception (at the end...
11
2255
by: dee | last post by:
OleDbCommand class like many .NET classes has the following description in its help file: "Thread Safety Any public static (Shared in Visual Basic) members of this type are safe for multithreaded operations. Any instance members are not guaranteed to be thread safe." I have 2 questions: 1. I thought dynamic variables are thread-safe since threads have their own
0
7718
by: gm | last post by:
Immediately after generating the Access application from the Source Safe project I get: "-2147467259 Could not use ''; file already in use." If Access database closed and then reopened I get: "-2147467259 The database has been place in a state by user 'Admin' on machine ..... that prevents it from being opened or locked."
15
2786
by: Laser Lu | last post by:
I was often noted by Thread Safety declarations when I was reading .NET Framework Class Library documents in MSDN. The declaration is usually described as 'Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.' So, does this mean All the static/shared methods written in .NET compatible programming language, such as C#, VB.NET, are guaranteed to be...
1
3601
by: johnlim20088 | last post by:
Hi, Currently I have 6 web projects located in Visual Source Safe 6.0, as usual, everytime I will open solution file located in my local computer, connected to source safe, then check out/check in some files and work on it. Let say, I want add new page to web project named websiteOrder.sln, i will open websiteOrder.sln in my local computer, connected to websiteOrder.sln located in Visual Source Safe 6.0(source safe located in another...
1
4627
by: jecheney | last post by:
Hi, Im currently using the following code for reading/writing to a network socket. private StreamReader clientStreamReader; private StreamWriter clientStreamWriter; .... TcpClient tcpClient = new TcpClient(server_host_name, server_port);
4
1928
by: George2 | last post by:
Hello everyone, Here is Bjarne's exception safe sample, http://www.research.att.com/~bs/3rd_safe.pdf template <class Tclass Safe {
44
7825
by: climber.cui | last post by:
Hi all, Does anyone have experience on the thread-safty issue with malloc()? Some people said this function provided in stdlib.h is not thread- safe, but someone said it is thread safe. Is it possible this function evolves from thread-unsafe to thread-safe in recent years? How could i find out? I am using the C library coming with GNU linux distribution. thanks a lot.
3
1525
by: =?Utf-8?B?anBhdHJjaWs=?= | last post by:
Don't see any official notice that compiled library dll's loaded in the BIN directory of an asp.net website need to be thread safe, but concurrent visits to the same web site sure bear this out. Does anyone know the answer to this?
1
4298
by: Philss100 | last post by:
Hi, I have been in the process of updating my code with security methods, and I've been learning this from http://msdn.microsoft.com/en-us/library/ms998258.aspx#pagguidelines0001_authorization (or "Security Guidelines: ASP.NET 2.0"). In the middle of the page under "When Constructing SQL Queries, Use Type Safe SQL Parameters" it says "Use type safe parameters when constructing SQL queries to avoid possible SQL injection attacks that can occur...
0
9595
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9432
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10232
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10059
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8891
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7420
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6682
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5313
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5454
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.