Win a copy of Programmers Guide to Apache Thrift this week in the Open Source forum!

- Post Reply Bookmark Topic Watch Topic
- New Topic

programming forums
Java
Mobile
Certification
Databases
Caching
Books
Engineering
Micro Controllers
OS
Languages
Paradigms
IDEs
Build Tools
Frameworks
Application Servers
Open Source
This Site
Careers
Other
all forums

this forum made possible by our volunteer staff, including ...

Marshals:

- Campbell Ritchie
- Devaka Cooray
- Knute Snortum
- Paul Clapham
- Tim Cooke

Sheriffs:

- Liutauras Vilda
- Jeanne Boyarsky
- Bear Bibeault

Saloon Keepers:

- Tim Moores
- Stephan van Hulst
- Ron McLeod
- Piet Souris
- Frits Walraven

Bartenders:

- Ganesh Patekar
- Tim Holloway
- salvin francis

posted 4 years ago

I have to print points on a circle in increments of -0.1, but when I use a number larger than 1.3, the list stops at 0.1 larger than negRadius, and I don't know why. (Assume the center is (0,0))

posted 4 years ago

You aren't clear about what you need to print out. What is increasing by 0.1 at a time?

Are you aware of the Math#hypot method, which is actually intended for calculating the radius of a circle for polar coordinates. You will probably find it simpler to use than calculating Pythagoras the long way.

You know that the locus of a circle can be defined as (*r*sinθ, *r*cosθ)?

You know that incrementing a double by 0.1 is a notorious example of the imprecision of floating‑point arithmetic? You can find the exact value of the double 0.1 here, and you can see it is very slightly greater than 0.1. So it is obvious that your loop will run not more than twenty times. Try it. It will confidently run twenty‑one times

Are you aware of the Math#hypot method, which is actually intended for calculating the radius of a circle for polar coordinates. You will probably find it simpler to use than calculating Pythagoras the long way.

You know that the locus of a circle can be defined as (

You know that incrementing a double by 0.1 is a notorious example of the imprecision of floating‑point arithmetic? You can find the exact value of the double 0.1 here, and you can see it is very slightly greater than 0.1. So it is obvious that your loop will run not more than twenty times. Try it. It will confidently run twenty‑one times

Campbell Ritchie

Marshal

Posts: 64471

225

posted 4 years ago

Avoid Math.pow(x, 2)

You will usually find x * x gives faster performance and is more precise.

You will usually find x * x gives faster performance and is more precise.

Damien Sky

Greenhorn

Posts: 14

1

posted 4 years ago

It is x (the x-coordinate of the point on the circle) that is decreasing by 0.1. I do not even know what a locus is.

I don't know of Math#hypot, but would it be useful since I'm calculating the y-value, not the hypotenuse?

Also, I have to use Math.pow(x, 2) because the lesson this assignment is for is a lesson on the Math class, and I have been told that if I just do things like x*x, I am "doing the computer's work for it" and I shouldn't be doing that. I will have points deducted if I do that.

The problem is not with that, it's just that it stops early. I was given a screenshot of what it should look like when it's run for radius = 1, and my values matched it.

I just figured out something else. I have this problem between radius values of 1.4 and 4.6, but values less than 1.4 or greater than 4.6 are fine. Even 10 worked fine.

I could use if(radius >= 1.4 && radius <= 4.6) to fix this, but I want to know why this problem is happening and if there is a different way to solve it.

I don't know of Math#hypot, but would it be useful since I'm calculating the y-value, not the hypotenuse?

Also, I have to use Math.pow(x, 2) because the lesson this assignment is for is a lesson on the Math class, and I have been told that if I just do things like x*x, I am "doing the computer's work for it" and I shouldn't be doing that. I will have points deducted if I do that.

The problem is not with that, it's just that it stops early. I was given a screenshot of what it should look like when it's run for radius = 1, and my values matched it.

I just figured out something else. I have this problem between radius values of 1.4 and 4.6, but values less than 1.4 or greater than 4.6 are fine. Even 10 worked fine.

I could use if(radius >= 1.4 && radius <= 4.6) to fix this, but I want to know why this problem is happening and if there is a different way to solve it.

posted 4 years ago

No it isn't, because a coordinate involves*two* numbers.

My suggestion is that you give us the requirements**exactly** as they were given to you, because "decreasing by 0.1" could mean almost anything.

Question: Is the idea that you should plot 10__different__ points on the *same* circle, or 10 similar points on *different* circles? Because by calling your control field "`radius`" you're suggesting the latter.

And if it's the first, should they be regularly spaced "around the clock"? If so, a better name for your control variable might be "`perimeter`".

Inquiring minds want to know...

Winston

Damien Sky wrote:It is x (the x-coordinate of the point on the circle) that is decreasing by 0.1.

No it isn't, because a coordinate involves

My suggestion is that you give us the requirements

Question: Is the idea that you should plot 10

And if it's the first, should they be regularly spaced "around the clock"? If so, a better name for your control variable might be "

Inquiring minds want to know...

Winston

"Leadership is nature's way of removing morons from the productive flow" - Dogbert

Articles by Winston can be found here

posted 4 years ago

- 1

To understand what's going wrong, you need to eliminate the parts of your program that don't make any difference to what you are asking about. Once done, you would have something like this:

By golly, when I run that, it stops before x reaches 1.4, too. Here's the output:

Now, ignore all the helpful tips you've gotten here about the Math class for the moment (and about coordinates being two numbers [Winston, where did you get that idea? ]). As we can see, your problem doesn't depend on circles, computing the other coordinate of a point on a circle, or the Math class at all. Instead,*something *is making your loop stop early. It's as though x drops below -1.4 one step too soon. Could that really be happening?

Let's push Java for some more information. Your printf only asks for one decimal place. Let's ask for more:

Here's the output:

No surprises there, right? Yet, what Campbell told you is correct:

He's right about that, yet our output seems to show no imprecision at all. How could Campbell be right when our output shows perfect precision? Well, let's go the other way and ask printf to show*no *decimal places:

Here's the output:

Whoa! We sure didn't change how we compute x at each pass through the for loop, yet it only seems to have three different values, each of which gets used more than once! How can that be? The answer is,*it can't be*. x actually is changing on each pass through the loop. Why doesn't it seem to change on our output? Because printf is rounding it to the number of decimal places we asked for which, in the last case, was zero. Rounded to zero places, a number like "1.1" is printed as "1." So is a number like "1.22," or even "1.20001." With that in mind, let's ask for a lot of decimal places:

You run this one yourself. The output is probably going to surprise you but, once you understand it, you will know the answer to your original question.

Good luck.

By golly, when I run that, it stops before x reaches 1.4, too. Here's the output:

Now, ignore all the helpful tips you've gotten here about the Math class for the moment (and about coordinates being two numbers [Winston, where did you get that idea? ]). As we can see, your problem doesn't depend on circles, computing the other coordinate of a point on a circle, or the Math class at all. Instead,

Let's push Java for some more information. Your printf only asks for one decimal place. Let's ask for more:

Here's the output:

No surprises there, right? Yet, what Campbell told you is correct:

...incrementing a double by 0.1 is a notorious example of the imprecision of floating‑point arithmetic...

He's right about that, yet our output seems to show no imprecision at all. How could Campbell be right when our output shows perfect precision? Well, let's go the other way and ask printf to show

Here's the output:

Whoa! We sure didn't change how we compute x at each pass through the for loop, yet it only seems to have three different values, each of which gets used more than once! How can that be? The answer is,

You run this one yourself. The output is probably going to surprise you but, once you understand it, you will know the answer to your original question.

Good luck.

"Il y a peu de choses qui me soient impossibles..."

posted 4 years ago

Erm, from Maps? Wiki admittedly says that it can be "one or more"; but I can't see how that would work for a circle (which is a 2-D shape) without an agreed centre, radius*and* "North". And even then, wouldn't it simply be a "bearing" or angle?

I know I'm not a Maths expert, but please tell me where I've gone wrong.

Winston

Stevens Miller wrote:Now, ignore all the helpful tips you've gotten here about the Math class for the moment (and about coordinates being two numbers [Winston, where did you get that idea? ]).

Erm, from Maps? Wiki admittedly says that it can be "one or more"; but I can't see how that would work for a circle (which is a 2-D shape) without an agreed centre, radius

I know I'm not a Maths expert, but please tell me where I've gone wrong.

Winston

Articles by Winston can be found here

posted 4 years ago

Do you mean "Maps," as in "graphical representations of things like terrain," or are you referring to some Java class called Maps? Anyway, where you went wrong was in saying,

A coordinate is a single number. A set of them (typically at least two, but one alone is okay) constitute "coordinates." In Damien's case, he is correct to the effect that his loop variable is the x-coordinate in the xy-plane containing his circle. An x-coordinate and a y-coordinate are each a single number. Together, in the xy-plane, they are a pair of coordinates that identify a unique point in the plane. More generally, any number of coordinates can identify a unique point in any n-dimensional space. (There are some boringly complicating extensions to this: for example, a lot of code behind 3-D graphics is written to handle four-coordinate vectors of "homogenous" coordinates, in the form of [x, y, z, w], where the point in 3-space is identified by the three coordinates (x/w, y/w, z/w). Believe it or not, this actually simplifies perspective transformations, since a four-coordinate vector can be multiplied by a 4x4 matrix, which can contain any number of rotations, translations, enlargements, and perspective transforms, all composited upon one another, to put a canonical object into a 3-D scene.)

Damien is trying to compute the y-coordinate of a circle as a function defined on a range of x-coordinate values (actually, since circles aren't functions along any axis in the cartesian plane, he's correctly computing pairs of y-coordinates from each x-coordinate, which, when he solves the problem he's having, may lead him to yet another problem, involving the taking of square roots of negative numbers, but not if he's careful). But, Damien's problem is entirely captured in Campbell's warning about the imprecision of floating-point variables. I'm just trying to help Damien see his problem for what it is, which has nothing to do with circles, powers of two, or what a coordinate is.

Winston Gutkowski wrote:

Stevens Miller wrote:Now, ignore all the helpful tips you've gotten here about the Math class for the moment (and about coordinates being two numbers [Winston, where did you get that idea? ]).

Erm, from Maps? Wiki admittedly says that it can be "one or more"; but I can't see how that would work for a circle (which is a 2-D shape) without an agreed centre, radiusand"North". And even then, wouldn't it simply be a "bearing" or angle?

I know I'm not a Maths expert, but please tell me where I've gone wrong.

Winston

Do you mean "Maps," as in "graphical representations of things like terrain," or are you referring to some Java class called Maps? Anyway, where you went wrong was in saying,

a coordinate involves two numbers.

A coordinate is a single number. A set of them (typically at least two, but one alone is okay) constitute "coordinates." In Damien's case, he is correct to the effect that his loop variable is the x-coordinate in the xy-plane containing his circle. An x-coordinate and a y-coordinate are each a single number. Together, in the xy-plane, they are a pair of coordinates that identify a unique point in the plane. More generally, any number of coordinates can identify a unique point in any n-dimensional space. (There are some boringly complicating extensions to this: for example, a lot of code behind 3-D graphics is written to handle four-coordinate vectors of "homogenous" coordinates, in the form of [x, y, z, w], where the point in 3-space is identified by the three coordinates (x/w, y/w, z/w). Believe it or not, this actually simplifies perspective transformations, since a four-coordinate vector can be multiplied by a 4x4 matrix, which can contain any number of rotations, translations, enlargements, and perspective transforms, all composited upon one another, to put a canonical object into a 3-D scene.)

Damien is trying to compute the y-coordinate of a circle as a function defined on a range of x-coordinate values (actually, since circles aren't functions along any axis in the cartesian plane, he's correctly computing pairs of y-coordinates from each x-coordinate, which, when he solves the problem he's having, may lead him to yet another problem, involving the taking of square roots of negative numbers, but not if he's careful). But, Damien's problem is entirely captured in Campbell's warning about the imprecision of floating-point variables. I'm just trying to help Damien see his problem for what it is, which has nothing to do with circles, powers of two, or what a coordinate is.

"Il y a peu de choses qui me soient impossibles..."

posted 4 years ago

Aha. My first mistake. I presume then it's called a 'coordinate' because there's a second number involved; maybe the 'origin'?

Yeah, that bit I knew (kind of).

Interesting. I can see I'm going to have to do a lot more reading on this.

Oh, OK. So if, for sake of argument, x = 1.0 is the "top" of the circle, he wants to know the y values as he goes linearly down the x axis in steps of 0.1 to 0, which can then be mirrored for the lower half of the semicircle.

*Now* I get it (I think). Tell me if I'm wrong.

Winston

Stevens Miller wrote:A coordinate is a single number.

Aha. My first mistake. I presume then it's called a 'coordinate' because there's a second number involved; maybe the 'origin'?

An x-coordinate and a y-coordinate are each a single number. Together, in the xy-plane, they are a pair of coordinates that identify a unique point in the plane. More generally, any number of coordinates can identify a unique point in any n-dimensional space.

Yeah, that bit I knew (kind of).

There are some boringly complicating extensions to this: for example, a lot of code behind 3-D graphics is written to handle four-coordinate vectors of "homogenous" coordinates, in the form of [x, y, z, w], where the point in 3-space is identified by the three coordinates (x/w, y/w, z/w). Believe it or not, this actually simplifies perspective transformations, since a four-coordinate vector can be multiplied by a 4x4 matrix, which can contain any number of rotations, translations, enlargements, and perspective transforms, all composited upon one another, to put a canonical object into a 3-D scene.

Interesting. I can see I'm going to have to do a lot more reading on this.

Damien is trying to compute the y-coordinate of a circle as a function defined on a range of x-coordinate values (actually, since circles aren't functions along any axis in the cartesian plane, he's correctly computing pairs of y-coordinates from each x-coordinate...

Oh, OK. So if, for sake of argument, x = 1.0 is the "top" of the circle, he wants to know the y values as he goes linearly down the x axis in steps of 0.1 to 0, which can then be mirrored for the lower half of the semicircle.

Winston

Articles by Winston can be found here

Damien Sky

Greenhorn

Posts: 14

1

posted 4 years ago

I created a double "increment" and changed the code to this:

It now shows the final x value and gives it y value as 0, but also gives y = 0 when x = negRadius + 2 * increment. How would I fix that?

It now shows the final x value and gives it y value as 0, but also gives y = 0 when x = negRadius + 2 * increment. How would I fix that?

posted 4 years ago

I think you're concentrating a bit too much on the code at the moment, and not on WHAT you need to do. Sorry for steering you wrong on the 'coordinates', but here I*do* know what I'm taking about (promise ).

1. Without going into the internals of floating-point numbers (eg,`double`) in detail, there is only *one* class of value that you can be sure will be held __exactly__: *whole numbers* (and there are limits for those too).

*Most* other values - and certainly most that are returned by functions - will be *approximations*.

One such value in particular is 0.1 (which is very likely why it was given to you for this problem). A`double` simply cannot hold 0.1 as an exact value - and for this reason, they tend to make very poor control values for loops. On the other hand:

`int one = 1;
`

double x = one / 10.0; (Note: the '.0' __is__ important; I'll leave you to discover why)

will set`x` to the *closest* value to 0.1 it's possible for a `double` to hold. Now, how do you think you might be able to use *that* knowledge to re-tool your loop?

2. StopCoding (←click).

You plainly know*roughly* what you want to do, but you haven't thought it through completely; which is why you're now having to resort to 'tweaking' to get it right. Write down exactly what you want to do, *in detail* and **in English** before you write any Java code. For one thing, it helps *you* understand the problem better; and for another, it makes the whole business of coding very much easier.

It's a pain when you're just dying to see results but believe me,*it works*. It's also a very good habit to get into for later on because - trust me - these problems are only going to get harder.

HIH. And if you're interested in more information about floating point values, bookmark this page.

Winston

Damien Sky wrote:I created a double "increment" and changed the code to this:

I think you're concentrating a bit too much on the code at the moment, and not on WHAT you need to do. Sorry for steering you wrong on the 'coordinates', but here I

1. Without going into the internals of floating-point numbers (eg,

One such value in particular is 0.1 (which is very likely why it was given to you for this problem). A

double x = one / 10.0;

will set

2. StopCoding (←click).

You plainly know

It's a pain when you're just dying to see results but believe me,

HIH. And if you're interested in more information about floating point values, bookmark this page.

Winston

Articles by Winston can be found here

posted 4 years ago

I was just having a look at this topic, and it seems strange that, as far as I can tell, no one has given

OP a clue on how to avoid these floating point inaccuracies.

Winston is right, use integer arithmatic. Suppose you have some segment [a, b], for which you want to

calculate some evenly spaced sequence [x(0) = a, x(1), x(2), .., x(n) = b].

Then the formula x(k) = a * (n - k) / n + b * k / n does miracles.

For instance (I've choosen n such that the increment = 0.1):

Edited: put the square root in

OP a clue on how to avoid these floating point inaccuracies.

Winston is right, use integer arithmatic. Suppose you have some segment [a, b], for which you want to

calculate some evenly spaced sequence [x(0) = a, x(1), x(2), .., x(n) = b].

Then the formula x(k) = a * (n - k) / n + b * k / n does miracles.

For instance (I've choosen n such that the increment = 0.1):

Edited: put the square root in

posted 4 years ago

- 1

Piet, the reason I haven't gone to the step you have is that the OP didn't seem to know that floating point numbers tend to be imprecise, nor why. His latest work-around is still somewhat problematic, but shows an improved understanding. We can just write a working version of his code for him, but, as I understand it, that's against local policy. Your solution works, but hides the nature of the problem, which I hope he will fully comprehend before this thread is resolved.

"Il y a peu de choses qui me soient impossibles..."

Piet Souris

Saloon Keeper

Posts: 3250

128

posted 4 years ago

In principle I agree. However, seeing that after your long reply, the discussion went

from homogenous coordinates to stop coding, I thought that a shortcut could

speed up things. Well, I wonder what OP has to say.

from homogenous coordinates to stop coding, I thought that a shortcut could

speed up things. Well, I wonder what OP has to say.

posted 4 years ago

Pretty close. He wants to go from 1.0 to -1.0 (the "top" of the circle is at x=0.0). My whole reason for being a pest about coordinates and the Math class is simply that his problem has nothing do with circles or any related complicating topics. He's just coping, as many of us have, with the fact that subtracting 0.1 from 1.0, twenty times, does*not *yield -1.0 as his final result. I just wanted him to focus on that, and that alone, until he came to grips with the rather mind-bending fact that computers are crap at doing sums. (Well, it was mind-bending to me, when I had to come to grips with it.)

Winston Gutkowski wrote:Oh, OK. So if, for sake of argument, x = 1.0 is the "top" of the circle, he wants to know the y values as he goes linearly down the x axis in steps of 0.1 to 0, which can then be mirrored for the lower half of the semicircle.

NowI get it (I think). Tell me if I'm wrong.

Winston

Pretty close. He wants to go from 1.0 to -1.0 (the "top" of the circle is at x=0.0). My whole reason for being a pest about coordinates and the Math class is simply that his problem has nothing do with circles or any related complicating topics. He's just coping, as many of us have, with the fact that subtracting 0.1 from 1.0, twenty times, does

"Il y a peu de choses qui me soient impossibles..."

posted 4 years ago

Hey, my words are golden. You should be grateful when I'm prolix .

Actually, Winston's oft-given advice to stop coding (I tend to word that as, "keep your hands where I can see them and step away from the mouse"), is applicable here. Damien needs to understand the nature of floating point numbers to know why his loop was working the way it was. Heh, when I first coped with this (which was in 1975), knowing how floating-point numbers were actually encoded was a kind of rite of passage for programmers. Today, Java's philosophy, that native types must be opaque, seems somewhat in conflict with knowing why integer types are (within their ranges) always exact, but floating types cannot be similarly trusted. My beloved "Core Java" introduces floating-point numbers by describing`float`s and `double`s in terms of how many "signficant digits" of precision they have. It then goes on to warn against using them in "financial" calculations, because of round-off (even explaining that neither a float nor a double can exactly represent the value 1/10). But, taken as a whole, a beginner could end up thinking, "Well, I'm computing the coordinates of points on a circle, not running a bank, so this isn't a financial calculation, and I've got a circle of radius 1.0, with steps of only 0.1, so six significant digits will certainly be enough for me." Indeed, if Java were to use binary-encoded decimal (something I would *not *support, of course) as the internal format of its floats, Damien's first program would have worked fine, and floats would be just as opaque as they are now. It's because they use the internal format that they do, that he is having a problem, and that opacity may, however unintentionally, be part of the reason.

Piet Souris wrote:In principle I agree. However, seeing that after your long reply, the discussion went

from homogenous coordinates to stop coding, I thought that a shortcut could

speed up things. Well, I wonder what OP has to say.

Hey, my words are golden. You should be grateful when I'm prolix .

Actually, Winston's oft-given advice to stop coding (I tend to word that as, "keep your hands where I can see them and step away from the mouse"), is applicable here. Damien needs to understand the nature of floating point numbers to know why his loop was working the way it was. Heh, when I first coped with this (which was in 1975), knowing how floating-point numbers were actually encoded was a kind of rite of passage for programmers. Today, Java's philosophy, that native types must be opaque, seems somewhat in conflict with knowing why integer types are (within their ranges) always exact, but floating types cannot be similarly trusted. My beloved "Core Java" introduces floating-point numbers by describing

"Il y a peu de choses qui me soient impossibles..."

Campbell Ritchie

Marshal

Posts: 64471

225

posted 4 years ago

Hahahahahahaha! Do you have to hold a Colt .45 as you say that?Stevens Miller wrote: . . . "keep your hands where I can see them and step away from the mouse" . . .

Or maybe that two's complement arithmetic and IEEE 754 numbers were well‑known before Java was developed and they took it for granted people knew how binary arithmetic works?Today, Java's philosophy, that native types must be opaque, seems somewhat in conflict with knowing why integer types are (within their ranges) always exact, but floating types cannot be similarly trusted. . . .

posted 4 years ago

Heavens, no! My weapon of choice is far more persuasive:

Man, if the people you hang with know about such things, I'd like to spend more time with them myself. For a newcomer to coding, I think that might be somewhat abstruse subject matter.

To pursue that a bit, though: is it safe to assume that opaque types will never change internally? I am guessing the language spec calls for a format, but I really don't know and, even if it does, does it say the format will never change? I was kind of embarrassed, when I started learning Java, to realize I didn't even know what "opaque" meant, in the context of a programming language. As I understand it now, however, the virtue of opacity is that I am neither supposed to care*nor know* how a type is structured internally, so I neither have to accommodate that structure, nor can I do anything that would rely on that structure never being changed in the future.

Good example of me still having a lot to learn. If I've got any of this wrong, please help me out.

Campbell Ritchie wrote:

Hahahahahahaha! Do you have to hold a Colt .45 as you say that?Stevens Miller wrote: . . . "keep your hands where I can see them and step away from the mouse" . . .

Heavens, no! My weapon of choice is far more persuasive:

Or maybe that two's complement arithmetic and IEEE 754 numbers were well‑known before Java was developed and they took it for granted people knew how binary arithmetic works?Today, Java's philosophy, that native types must be opaque, seems somewhat in conflict with knowing why integer types are (within their ranges) always exact, but floating types cannot be similarly trusted. . . .

Man, if the people you hang with know about such things, I'd like to spend more time with them myself. For a newcomer to coding, I think that might be somewhat abstruse subject matter.

To pursue that a bit, though: is it safe to assume that opaque types will never change internally? I am guessing the language spec calls for a format, but I really don't know and, even if it does, does it say the format will never change? I was kind of embarrassed, when I started learning Java, to realize I didn't even know what "opaque" meant, in the context of a programming language. As I understand it now, however, the virtue of opacity is that I am neither supposed to care

Good example of me still having a lot to learn. If I've got any of this wrong, please help me out.

"Il y a peu de choses qui me soient impossibles..."

Campbell Ritchie

Marshal

Posts: 64471

225

posted 4 years ago

It does specify that ints longs shorts and bytes are two's complement, chars are unsigned, and that floats and doubles are IEEE 754 numbers in 32 and 64 bits respectively, in the JLS, so they ought not to change ever.

We used to teach binary integer arithmetic (in 8 bits) and floating point arithmetic (IEEE 754 in 32 bits) to our freshers, so they should have some idea how the numbers are represented long before getting their BSc.

We used to teach binary integer arithmetic (in 8 bits) and floating point arithmetic (IEEE 754 in 32 bits) to our freshers, so they should have some idea how the numbers are represented long before getting their BSc.

Campbell Ritchie

Marshal

Posts: 64471

225

posted 4 years ago

- 1

You need to know about the structure of primitives so you know about overflow (integers) and underflow (floating‑point only). Actually floating‑point numbers can overflow too, in which case you get ±∞.

posted 4 years ago

That raises a very important pedagogical point: teaching someone to program before they know the limitations of the primitive types they will be working with is kind of like teaching someone how to build a house before they know how much weight a foundation can bear. Damien's problem should have been the actual subject matter of his assignment. Or, more precisely, he should have been given an assignment that would reveal to him, and help me learn to cope with, the limitations of floating-point numbers. (I suppose he might have been given such an assignment, and we just don't know about it, but that appears unlikely, to me.)

I never got a bachelor's in CS (mine's in physics). My master's program must have assumed we already knew this stuff, because it never came up directly. In my own case, I learned about two's-complement and various schemes for representing floats by reading Byte and working with a textbook the Sperry-Univac company used for an in-house course on computers. (My dad got that for me from a friend, when I was 15. I read the whole thing and they even let me take the final exam. I still have the certificate that says I passed, somewhere. The bums declined to give me a summer job, regardless, but I see that as their loss.)

But, yeah, this isn't something you can ignore if you're going to write computer programs. As dry as it may be to students hoping to write Xbox games, it really does need to be part of their primary education.

Campbell Ritchie wrote:You need to know about the structure of primitives so you know about overflow (integers) and underflow (floating‑point only). Actually floating‑point numbers can overflow too, in which case you get ±∞.

That raises a very important pedagogical point: teaching someone to program before they know the limitations of the primitive types they will be working with is kind of like teaching someone how to build a house before they know how much weight a foundation can bear. Damien's problem should have been the actual subject matter of his assignment. Or, more precisely, he should have been given an assignment that would reveal to him, and help me learn to cope with, the limitations of floating-point numbers. (I suppose he might have been given such an assignment, and we just don't know about it, but that appears unlikely, to me.)

I never got a bachelor's in CS (mine's in physics). My master's program must have assumed we already knew this stuff, because it never came up directly. In my own case, I learned about two's-complement and various schemes for representing floats by reading Byte and working with a textbook the Sperry-Univac company used for an in-house course on computers. (My dad got that for me from a friend, when I was 15. I read the whole thing and they even let me take the final exam. I still have the certificate that says I passed, somewhere. The bums declined to give me a summer job, regardless, but I see that as their loss.)

But, yeah, this isn't something you can ignore if you're going to write computer programs. As dry as it may be to students hoping to write Xbox games, it really does need to be part of their primary education.

"Il y a peu de choses qui me soient impossibles..."

Piet Souris

Saloon Keeper

Posts: 3250

128

posted 4 years ago

OP is having a minor problem with a boundary, and so he's facing some inaccuracy

that comes with floating points. That's all. Why OP should stop coding and follow a

course in IEEE 754: it seems a bit heavy to me.

that comes with floating points. That's all. Why OP should stop coding and follow a

course in IEEE 754: it seems a bit heavy to me.

posted 4 years ago

Piet, it's not "some innaccuracy" that is causing his problem. It's the fact that his code is written with the assumption that a computer using Java's type of floating-point numbers can add 0.1 and 0.1, and get 0.2, when it can't. That's a very, very common error for new programmers to make and, until they understand at least *something *about how digital computers store floating-point numbers, it can be virtually impossible to understand.

If he were computing points on a circle by entering an x and obtaining a y, the fact that floats/doubles are imprecise would, as you say, impose some inaccuracy upon his result. But his real problem is that he is trying to iterate a function over evenly space values in its range, and his approach is failing for a rather subtle reason. It doesn't matter that he's computing points on a circle (or even that he's computing anything based on his x value at all). What matters is that he wants his computer to generate a set of values (specifically, [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0, -0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7, -0.8, -0.9, -1.0]), and that, although his code is arithmetically correct, it doesn't work. The reason it doesn't work has nothing to do with his math (which is fine). It doesn't work because Java literally cannot store the number 0.1 in a float (or a double). It stores a nearby value that, for many purposes, is good enough. But, when used to increment or decrement a loop-control variable, it's not that it isn't sufficiently accurate: it's that it doesn't work at all. (Put another way, he wants 21 values from his loop, and he's only getting 20, because floats and doubles can't do exact math. That's not an inaccuracy; it's a outright failure to meet his objective.)

(Oh actually, his program seems to work over the range [1, -1]. It breaks when he tries to cover the range [1.3, -1.3], so he is really trying to generate 27 values when he's only getting 26. Same point applies, though.)

If he were computing points on a circle by entering an x and obtaining a y, the fact that floats/doubles are imprecise would, as you say, impose some inaccuracy upon his result. But his real problem is that he is trying to iterate a function over evenly space values in its range, and his approach is failing for a rather subtle reason. It doesn't matter that he's computing points on a circle (or even that he's computing anything based on his x value at all). What matters is that he wants his computer to generate a set of values (specifically, [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0, -0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7, -0.8, -0.9, -1.0]), and that, although his code is arithmetically correct, it doesn't work. The reason it doesn't work has nothing to do with his math (which is fine). It doesn't work because Java literally cannot store the number 0.1 in a float (or a double). It stores a nearby value that, for many purposes, is good enough. But, when used to increment or decrement a loop-control variable, it's not that it isn't sufficiently accurate: it's that it doesn't work at all. (Put another way, he wants 21 values from his loop, and he's only getting 20, because floats and doubles can't do exact math. That's not an inaccuracy; it's a outright failure to meet his objective.)

(Oh actually, his program seems to work over the range [1, -1]. It breaks when he tries to cover the range [1.3, -1.3], so he is really trying to generate 27 values when he's only getting 26. Same point applies, though.)

"Il y a peu de choses qui me soient impossibles..."

Campbell Ritchie

Marshal

Posts: 64471

225

posted 4 years ago

Are you still with us, Damien Sky

You have opened up an interesting discussion here. When I started programming Java® I was told never to use doubles or floats in loops because of such imprecision.

You can get tenths like this:-…but if you enter a negative number your loop will never start.

Have you thought of this formula for the*y* coordinates?

*θ* = r *cos*⁻¹x

*y* = r *sin*θ

There are methods in the Math class for sin() and cos⁻¹ (I think acos()).

You have opened up an interesting discussion here. When I started programming Java® I was told never to use doubles or floats in loops because of such imprecision.

You can get tenths like this:-…but if you enter a negative number your loop will never start.

Have you thought of this formula for the

There are methods in the Math class for sin() and cos⁻¹ (I think acos()).

Campbell Ritchie

Marshal

Posts: 64471

225

posted 4 years ago

In my integer loop you would enter 13 for a radius of 1.3.

Piet Souris

Saloon Keeper

Posts: 3250

128

posted 4 years ago

The difference between you and me (in this respect) is that you consider this issue

far more fundamental than I do. And I respect your attempts to make the

inaccuracy that comes with floating points, clear to Damien. I can't give you a

cow for that, but accept my virtual one.

I only hope we didn't scare Damien off!

Greetz,

Piet

Stevens Miller wrote: (...)

The difference between you and me (in this respect) is that you consider this issue

far more fundamental than I do. And I respect your attempts to make the

inaccuracy that comes with floating points, clear to Damien. I can't give you a

cow for that, but accept my virtual one.

I only hope we didn't scare Damien off!

Greetz,

Piet

posted 4 years ago

Popped back to this thread after a while. And I'm going to try and answer that (especially since I'm the one that wrote the StopCoding page ).

It's the same as the reason that I'm very grateful to have someone like you around when I make a mathematical fallacy. I'm NOT a mathematician, but I do at least know that it's possible for me to make dangerous assumptions based on what I*think* to be true. And I need a Piet to tell me when I'm wrong.

If Damien doesn't understand*why* floating-point values have these inbuilt "gotchas" (and I'm not sure that he needs to read the entire IEEE-754 spec; Goldberg explains it pretty succinctly) he runs the risk of simply learning this example by rote, and/or not recognising it when it comes up in other guises (eg, currency calculations).

StopCoding is along the same lines, except that it's*procedural* advice.

When you start out programming, the first thing you do is CODE; and if you're smart, you can actually get quite a way by simply coding, because you can store an entire algorithm in your head. But there comes a point at which that process breaks down - and if you've never learned any other way of doing things, it usually breaks down catastrophically.

It also manifests itself*before then* in an increasing frustration at "why things don't work". The poster feels that "it ought to be simple", but it __isn't__; and they find they're making basic mistakes. And the reason (at least in my opinion) is that they've only ever been used to dealing with a problem *as a whole*, and as problems increase in complexity they get overwhelmed by the scope - and hence they get early lessons in debugging and (even worse) "tweaking".

I think it's also sound psychology. How many times have you been told, when you're desperately trying to remember something that's just maddeningly out of reach:

Forget about it. You'll remember when you're thinking about something else.

Well, the same is true of logic. And stopping coding - especially if you remember the other part of that advice:*turn your computer OFF* - forces you into a different mindset. You can't code, so you're forced to *think*. Most pros I know spend very little time coding, and actually consider it the most boring part of their job, because all it involves is translating what they *already know* into Java (or whatever).

I should add that it's BTDTGTTS advice.

My TGIF 2¢-worth.

Winston

PS: Happy Halloween everybody.

Piet Souris wrote:OP is having a minor problem with a boundary, and so he's facing some inaccuracy

that comes with floating points. That's all. Why OP should stop coding and follow a

course in IEEE 754: it seems a bit heavy to me.

Popped back to this thread after a while. And I'm going to try and answer that (especially since I'm the one that wrote the StopCoding page ).

It's the same as the reason that I'm very grateful to have someone like you around when I make a mathematical fallacy. I'm NOT a mathematician, but I do at least know that it's possible for me to make dangerous assumptions based on what I

If Damien doesn't understand

StopCoding is along the same lines, except that it's

When you start out programming, the first thing you do is CODE; and if you're smart, you can actually get quite a way by simply coding, because you can store an entire algorithm in your head. But there comes a point at which that process breaks down - and if you've never learned any other way of doing things, it usually breaks down catastrophically.

It also manifests itself

I think it's also sound psychology. How many times have you been told, when you're desperately trying to remember something that's just maddeningly out of reach:

Forget about it. You'll remember when you're thinking about something else.

Well, the same is true of logic. And stopping coding - especially if you remember the other part of that advice:

I should add that it's BTDTGTTS advice.

My TGIF 2¢-worth.

Winston

PS: Happy Halloween everybody.

Articles by Winston can be found here

posted 4 years ago

Is it just a coincidence or is it a disturbing trend that more programmers do their work with a mouse these days? I for one still use a keyboard to program. In fact, I'm trying to free myself from having to use a mouse.

Stevens Miller wrote:Winston's oft-given advice to stop coding (I tend to word that as, "keep your hands where I can see them and step away from the mouse")

Is it just a coincidence or is it a disturbing trend that more programmers do their work with a mouse these days? I for one still use a keyboard to program. In fact, I'm trying to free myself from having to use a mouse.

*Practice only makes habit, only perfect practice makes perfect.*—every music teacher ever
*Practice mindfully by doing the right things and doing things right.*— Junilu

[How to Ask Questions] [How to Answer Questions]

posted 4 years ago

Get a copy of Solaris (if you still can) and turn the desktop off. Still the best Unix AFAIC - although I'm told that you can do similar things with Debian.

Winston

Junilu Lacar wrote:In fact, I'm trying to free myself from having to use a mouse.

Get a copy of Solaris (if you still can) and turn the desktop off. Still the best Unix AFAIC - although I'm told that you can do similar things with Debian.

Winston

Articles by Winston can be found here

Damien Sky

Greenhorn

Posts: 14

1

posted 4 years ago

My teacher has informed me that she worded her question wrong. It was only meant to be run for a radius of 1 with varying increments, not radii.

Consider Paul's rocket mass heater. |

- Post Reply Bookmark Topic Watch Topic
- New Topic

Boost this thread!