Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C (http://www.go4expert.com/forums/c/)
-   -   beginner stuff (http://www.go4expert.com/forums/beginner-stuff-t22454/)

kaporal_p 17Jun2010 08:02

beginner stuff
 
Hey,

I'm a total beginner going through C for dummies, which seems to be a good starting point.

I got to this exercise where I don't understand the output. It's a little program that calculates simple logs. here's the code

Code:

{
    double ln,x;
                 
    for(x=0.1;x<6.0;x+=0.1)             
    {
        ln = log(x);             
        printf("ln(%3.1f) = %f\n", x, ln); 
    }
    return(0);

When I run the code the loop goes on through to 6.0. Why doesn't it stop at 5.9 since the 'test' is x<6.0?

The way I think the for loop works is
(initial condition; test; incrementation)
where the initial condition is tested, if true it is applied in a function.
THEN it is incremented and then the loop starts again. Is this wrong?

Because if it's not, then why 6.0. I don't like this 6.0.

Thanks

shabbir 17Jun2010 08:28

Re: beginner stuff
 
In floating at times it is 5.999 and not 6.0 and see if that is the case. Precision is how you should use to loop with floats.

kaporal_p 17Jun2010 08:58

Re: beginner stuff
 
Hi, thanks for answering,

I'm not sur I understand what you mean.

Do you mean there is uncertainty with float variables and that the value could oscillate between 5.999 and 6.0?

But even if it is so, if for a fraction of a second it is 6.0 and it enters the loop at that moment, the loop shouldn't process it.

Or do you mean the condition is oscillating between x<5.999 and x<6.0? But even then the loop should reject it.

Sorry, I don't get it yet, could you push the explanation a little bit further?

Thanks

shabbir 17Jun2010 11:21

Re: beginner stuff
 
Does it loop for 6.1? My guess would be no.

xpi0t0s 17Jun2010 12:50

Re: beginner stuff
 
On computers, numbers are stored in binary. And they have limited storage space, so when the conversion reaches that limit, it stops. Think of the decimal representations of fractions like 1/3 and 1/7 and now suppose that you had to write out 1/3 as precisely as possible using decimal representation...but only six significant figures. You would have to stop at 0.333333. Does 0.333333 = 1/3? No, of course not. 1/7=0.(142857) with the 142857 part repeated ad infinitum, so 0.142857 would be the six digit representation of 1/7 with the same problem.

Try converting 0.1 to binary and you will see the problem. I'll get you started; the left hand column is the binary representation of 0.1:

0 0.1<1
. decimal/binary point
0 0.1<0.5
0 0.1<0.25
0 0.1<0.125
1 0.1>0.0625
0 0.0375<0.03125
1 0.0375>0.015625
... and see if this ever terminates. You can use a spreadsheet to make this easier.

If it never terminates then there is a difference - an error - between the binary representation of 0.1 and 0.1 itself. And your loop multiplies this error by 60 by adding it to the loop variable sixty times.

What's the solution? Floating point numbers are inaccurate, so you cannot say "if float1==float2" and expect the result to be meaningful. One solution is to allow for an error, for example your x only uses two significant figures so instead of the simplistic "x<6.0" you could do a subtraction and compare the result with an error term, such as "abs(x-6.0) < 0.001".

A better solution in this case is to use integers (don't change x to int though) as they are more accurate than floats. Loop x from 1 to 60 and in the iteration use "x/10.0"; this way the error is not compounded as the loop progresses.

By the way, your program wrongly assumes that ln==log. ln means log base e; it's the natural logarithm. log without a specified base is usually base 10.

kaporal_p 17Jun2010 23:42

Re: beginner stuff
 
To shabbir: you guessed right, it does'nt loop for 6.1

To xpi0t0s : I tried this
Code:

for(x=1;x<60;x+=1/10.0)
and it works, but I have yet to grasp wher the magic happens...

Since 1/10 is 0.1, isn't the result 0.1 what should become the iteration value, therefore as problematic as a straight 0.1? (is my question understandable???)

Or is it because divider and dividend are both integers (1 and 10) ant that these are the values used by the loop as iteration 'agents'?

But this brings another question, where are float values needed?

As for ln = log(x). In the book I'm using, the author says :

"The log() function computes the natural logarithm of a value."
"The log10() function computes the base 10 logarithm for a value."

So if this is the way C processes logs, in saying "ln = log(x)" I thought he was simply calculating the natural log of x "log(x)" and assingning it's value to the variable 'ln' for user understadability.

Does that make sense?

Thanks

xpi0t0s 18Jun2010 03:25

Re: beginner stuff
 
That's not what I meant at all. Don't know why it works, it shouldn't, because you're now counting from 1 to 60 in tenths, so that should be around 600 iterations. What I meant was to count from 1 to 60 in 1's, as opposed to 0.1 to 6.0 in 0.1's, so in other words multiplying the whole lot by 10, then in the loop using x/10.0 instead of x as is currently the case.

So what compiler are you using that thinks 60*10=60 instead of 600? An ancient one like Turbo C 3.0, which seems very popular for no obvious reason?

ln/log, well I guess it depends on the math library you're using. If your math library uses log for ln and log10 for log that's fine. I was just saying the output should reflect reality.

kaporal_p 18Jun2010 05:11

Re: beginner stuff
 
You're so right!

When I ran the program, I just took a look at the last result, which wasn't 6.0 but 5.9 and thought everythink was fine... but there was in fact 600 iterations... oops

So now I understand what you meant. And not only does it really work, but it's also a more elegant way of solving the problem.

Thanks a lot.

btw, I'm using the Vim compiler, for the colors!

xpi0t0s 18Jun2010 12:06

Re: beginner stuff
 
Vim isn't a compiler, it's an editor. Don't confuse your tools. You edit programs with a text editor, then save and exit (recommended, cos if you shell out, then edit again, you can get into an interesting loop of confusion, especially if you forgot to save before shelling out, as in "hey, I fixed that!"). Compiling is done in several steps, often merged, but they are:

preprocess, where lines starting with # are handled;
compile, where C code is converted to object code (.o or .obj);
link, where object files are joined together with libraries to create an executable.

Preprocessing is often invoked directly by the compiler but some compilers allow you to invoke that stage separately, which is sometimes helpful (you won't need it yet though).

kaporal_p 18Jun2010 20:27

Re: beginner stuff
 
So, I'm editing in Vim, then I run the programs in the command prompt (RUN cmd). Does that mean that the command prompt is a compiler? Does that mean there are more 'convivial' ways to run simple code than the little black square I'm now used to see? Could you please suggest one?

Also, I'm learning C because I started doing Arduino projects and fast realized I needed to learn basic coding. In Arduino, you code and compile (and preprocess and link I guess)in the same 'interface', so, to me, it seems as if editing and compiling are joined for Arduino. Does this kind of programing environnement exist for C? Or is it better to have separate entities for reasons I have yet to understand?

Thanks. I really appreciate your advices, especially since I'm getting started, it's easy to go in the wrong direction to realize it only a decade later...


All times are GMT +5.5. The time now is 10:19.