Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > -atof- function , example from section 4.2 K&R2

Reply
Thread Tools

-atof- function , example from section 4.2 K&R2

 
 
arnuld
Guest
Posts: n/a
 
      04-04-2008
This is the example from section 4.2, page 71 of K&R2:


double atof( char s[] )
{
int i, sign;
double val, power;


for( i = 0; isspace( s[i] ); ++i )
{
/* skipe the leading whitespace */
}

sign = ( (s[i] == '-') ? -1 : 1 );

if( s[i] == '+'|| s[i] == '-' )
{
++i;
/* skip the leading sign, of any */
}

for( val = 0.0; isdigit( s[i] ); ++i )
{
val = (10.0 * val) + (s[i] - '0');

/* s[i] - '0' (zero in quotes)
* always gives "int i" as output
*/
}

if( s[i] == '.' )
{
++i;
/* skip the dot(.) of a floating point */
}

for( power = 1.0; isdigit( s[i] ); ++i )
{
val = (10.0 * val) + (s[i] - '0');
power *= 10.0;
}

return sign * val / power;
}


I can't really think of that kind of clever-tricks shown here. checking
for leading space and dot (.) are fine,they are very general things and
easily come to my mind but look at how cleverly the K&R created the
expressions like (val = 10.0 * val) and (power *= 10.0). these loops
using variables "val" and "power" are pretty much the work of people with
high IQs. After some work I can understand them but I can not create them
at very 1st place, I dont have that kind of thinking.

These tricks never came to my mind. Is this what we call programming ? if
yes, it is pretty much harder to come to my mind, may be never. I just do
not think this way.

 
Reply With Quote
 
 
 
 
Nick Keighley
Guest
Posts: n/a
 
      04-04-2008
On 4 Apr, 08:12, arnuld <loot...@shooting.com> wrote:

> This is the example from section 4.2, page 71 of K&R2:
>
> double atof( char s[] )
> {
> * int i, sign;
> * double val, power;
>
> * for( i = 0; isspace( s[i] ); ++i )
> * * {
> * * * /* skipe the leading whitespace */
> * * }
>
> * sign = ( (s[i] == '-') ? -1 : 1 );
>
> * if( s[i] == '+'|| s[i] == '-' )
> * * {
> * * * ++i;
> * * * /* skip the leading sign, of any */
> * * }
>
> * for( val = 0.0; isdigit( s[i] ); ++i )
> * * {
> * * * val = (10.0 * val) + (s[i] - '0');
>
> * * * /* s[i] - '0' (zero in quotes)
> * * * ** always gives "int i" as output
> * * * **/
> * * }
>
> * if( s[i] == '.' )
> * * {
> * * * ++i;
> * * * /* skip the dot(.) of a floating point */
> * * }
>
> * for( power = 1.0; isdigit( s[i] ); ++i )
> * * {
> * * * val = (10.0 * val) + (s[i] - '0');
> * * * power *= 10.0;
> * * }
>
> * return sign * val / power;
>
> }
>
> I can't really think of that kind of clever-tricks shown here.


I didn't think they were *that* clever

> checking
> for leading space and dot (.) are fine,they are very general things and
> easily come to my mind but look at how cleverly the K&R created the
> expressions *like (val = 10.0 * val)


how *else* would you code that?

> and (power *= 10.0).


which is just short hand for power = power * 10;

these seem fairly easy to me, but then I was weaned
on stuff like this. Some of it in Fortran...


> these loops
> using variables "val" and "power" are pretty much the work of people with
> high IQs. *


weel I don't foubt the Mr R has a high IQ, but I don't
see the examples you give as demonstrating it.

The trick is to look for patterns (that's about half
the job of programming). The power one is just stepping
through powers of 10 (1, 10, 100, 1000...).


> After some work I can understand them but I can not create them
> at very 1st place, I dont have that kind of thinking.


the trick is to catch repititions in your program text and
then trying to come up with a pattern that eliminates the
repetition.



> These tricks never came to my mind. Is this what we call programming ?


part of the job.


> if
> yes, it is pretty much harder to come to my mind, may be never. I just do
> not think this way.


all I can suggest it practice. Maybe have a look at
http://mitpress.mit.edu/sicp/
(it can be hard going so try the online version
before you consider buying)


--
Nick Keighley




 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      04-04-2008
On Fri, 04 Apr 2008 12:42:14 +0530, arnuld <>
wrote:

>This is the example from section 4.2, page 71 of K&R2:


No it isn't.

>
>
>double atof( char s[] )
>{
> int i, sign;
> double val, power;


If your are going to quote the book, don't change the order.

>
>
> for( i = 0; isspace( s[i] ); ++i )


Why did you change the third clause?

> {
> /* skipe the leading whitespace */
> }
>
> sign = ( (s[i] == '-') ? -1 : 1 );


Why did you add superfluous parentheses?

>
> if( s[i] == '+'|| s[i] == '-' )
> {
> ++i;


Why did you change this statement?

> /* skip the leading sign, of any */
> }


Why did you add superfluous braces?

>
> for( val = 0.0; isdigit( s[i] ); ++i )


Why did you change the third clause?

> {
> val = (10.0 * val) + (s[i] - '0');


Why did you add superfluous parentheses?

>
> /* s[i] - '0' (zero in quotes)
> * always gives "int i" as output
> */


This comment is not in the book, which is good since it is obviously
wrong.

> }
>
> if( s[i] == '.' )
> {
> ++i;


Why did you change this statement?

> /* skip the dot(.) of a floating point */
> }
>
> for( power = 1.0; isdigit( s[i] ); ++i )


Why did you change the third clause?

> {
> val = (10.0 * val) + (s[i] - '0');


Why did you add superfluous parentheses?

> power *= 10.0;
> }
>
> return sign * val / power;
>}

snip


Remove del for email
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      04-04-2008
Nick Keighley wrote:
> arnuld <loot...@shooting.com> wrote:
>
>> This is the example from section 4.2, page 71 of K&R2:
>>
>> double atof( char s[] )
>> {
>> int i, sign;
>> double val, power;
>>
>> for( i = 0; isspace( s[i] ); ++i )
>> {
>> /* skipe the leading whitespace */
>> }
>>
>> sign = ( (s[i] == '-') ? -1 : 1 );
>>
>> if( s[i] == '+'|| s[i] == '-' )
>> {
>> ++i;
>> /* skip the leading sign, of any */
>> }
>>
>> for( val = 0.0; isdigit( s[i] ); ++i )
>> {
>> val = (10.0 * val) + (s[i] - '0');
>>
>> /* s[i] - '0' (zero in quotes)
>> * always gives "int i" as output
>> */
>> }
>>
>> if( s[i] == '.' )
>> {
>> ++i;
>> /* skip the dot(.) of a floating point */
>> }
>>
>> for( power = 1.0; isdigit( s[i] ); ++i )
>> {
>> val = (10.0 * val) + (s[i] - '0');
>> power *= 10.0;
>> }
>>
>> return sign * val / power;
>>
>> }
>>
>> I can't really think of that kind of clever-tricks shown here.

>
> I didn't think they were *that* clever
>
>> checking
>> for leading space and dot (.) are fine,they are very general things and
>> easily come to my mind but look at how cleverly the K&R created the
>> expressions like (val = 10.0 * val)

>
> how *else* would you code that?
>
>> and (power *= 10.0).

>
> which is just short hand for power = power * 10;
>
> these seem fairly easy to me, but then I was weaned
> on stuff like this. Some of it in Fortran...
>
>> these loops
>> using variables "val" and "power" are pretty much the work of people with
>> high IQs.

>
> weel I don't foubt the Mr R has a high IQ, but I don't
> see the examples you give as demonstrating it.
>
> The trick is to look for patterns (that's about half
> the job of programming). The power one is just stepping
> through powers of 10 (1, 10, 100, 1000...).
>
>> After some work I can understand them but I can not create them
>> at very 1st place, I dont have that kind of thinking.

>
> the trick is to catch repititions in your program text and
> then trying to come up with a pattern that eliminates the
> repetition.
>
>> These tricks never came to my mind. Is this what we call programming ?

>
> part of the job.
>
>> if
>> yes, it is pretty much harder to come to my mind, may be never. I just do
>> not think this way.

>
> all I can suggest it practice. Maybe have a look at
> http://mitpress.mit.edu/sicp/
> (it can be hard going so try the online version
> before you consider buying)


Also consider how much clearer the whole routine becomes when the
extra vertical clutter is removed:

double atof(char s[]) {
int i, sign;
double val, power;

for (i = 0; isspace(s[i]); ++i) continue; /* skip whitespace */

sign = ((s[i] == '-') ? -1 : 1);
if (s[i] == '+' || s[i] == '-') ++i; /* skip any leading sign */

for (val = 0.0; isdigit(s[i]); ++i)
val = (10.0 * val) + (s[i] - '0'); /* evaluate */

if (s[i] == '.') ++i; /* skip the dot (.) of a floating point */

for (power = 1.0; isdigit(s[i]); ++i) {
val = (10.0 * val) + (s[i] - '0'); /* eval post decimal */
power *= 10.0;
}
return sign * val / power;
}

(this is one of my fetishes)

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
danzona@excite.com
Guest
Posts: n/a
 
      04-04-2008

On Fri, 04 Apr 2008 12:42:14 +0530, arnuld <>
wrote:

>This is the example from section 4.2, page 71 of K&R2:

<snip>
> for( val = 0.0; isdigit( s[i] ); ++i )
> {
> val = (10.0 * val) + (s[i] - '0');
>
> /* s[i] - '0' (zero in quotes)
> * always gives "int i" as output
> */
> }

<snip>

>I can't really think of that kind of clever-tricks shown here...
>
>These tricks never came to my mind. Is this what we call programming ?


Programming is an iterative process. How many iterations you want to
make is up to you to some extent but may also be impacted by
performance or memory requirements.

I've singled out one section of the code you posted since the comment
you added shows that you see what is happening.

The purpose of this section is to determine the integer portion of the
string (after all leading white space has been skipped).

A person taking their first stab at this part of the code might write:

val = 0.0;
while(isdigit(s[i]))
{
val *= 10.0;
val += s[i] - '0';
i++;
}

Some people might stop here because the code is clear and does what it
is supposed to. However, there is a school of thought that the best
way to write maintainable code is to have the code be as tight as
possible. Code will be better understood by the next person if each
line does one straightforward thing. (This can be problematic because
code that is too tight might also be too cryptic - a good programmer
strikes the proper balance.)

This code can be easily tightened up to:
val = 0.0;
while(isdigit(s[i]))
val = val * 10.0 + s[i++] - '0';

Again, some might stop here. But look at what the code does: we have
an initialization, a test for exit, a process, and an increment. That
is the definition of the for loop. Which leads to the code in K&R.
 
Reply With Quote
 
Dann Corbit
Guest
Posts: n/a
 
      04-04-2008
"arnuld" <> wrote in message
newsan.2008.04.04.07.12.13.481180.9914@shooting. com...
> This is the example from section 4.2, page 71 of K&R2:

[snip of tweaked exercise]
> I can't really think of that kind of clever-tricks shown here. checking
> for leading space and dot (.) are fine,they are very general things and
> easily come to my mind but look at how cleverly the K&R created the
> expressions like (val = 10.0 * val) and (power *= 10.0). these loops
> using variables "val" and "power" are pretty much the work of people with
> high IQs. After some work I can understand them but I can not create them
> at very 1st place, I dont have that kind of thinking.


You don't have to be a genius of any sort to think of this sort of thing.
Each subsequent digit is ten times larger than the one that preceded it. We
learned that in grade school.

> These tricks never came to my mind. Is this what we call programming ? if
> yes, it is pretty much harder to come to my mind, may be never. I just do
> not think this way.


If you should happen to write down using pencil and paper the steps you go
through to recognize the value of a number, then these same steps will work
when you make the computer do them. You are making this problem much harder
than it really is. If you put the book out of sight and write your own
version, you will find it is remarkably similar to theirs.

My answer to this exercise is on Richard Heathfield's site.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      04-04-2008
wrote:
>

.... snip ...
>
> This code can be easily tightened up to:
> val = 0.0;
> while(isdigit(s[i]))
> val = val * 10.0 + s[i++] - '0';
>
> Again, some might stop here. But look at what the code does:
> we have an initialization, a test for exit, a process, and an
> increment. That is the definition of the for loop. Which leads
> to the code in K&R.


And that tightening can lead to an error. The term "s[i++] - '0'"
should be firmly wrapped in a set of parenthesis. Otherwise errors
can occur when the magnitude of val suddenly exceeds a magic
threshold, and the subtraction of '0' does not work correctly.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
Joachim Schmitz
Guest
Posts: n/a
 
      04-05-2008
Richard Heathfield wrote:
> CBFalconer said:
>
> <snip>
>>
>> Also consider how much clearer the whole routine becomes when the
>> extra vertical clutter is removed:

>
> Consider how much clutter you have left, both vertical and horizontal!
>
> Before:
>
>> double atof(char s[]) {
>> int i, sign;
>> double val, power;
>>
>> for (i = 0; isspace(s[i]); ++i) continue; /* skip whitespace */
>>
>> sign = ((s[i] == '-') ? -1 : 1);
>> if (s[i] == '+' || s[i] == '-') ++i; /* skip any leading sign */
>>
>> for (val = 0.0; isdigit(s[i]); ++i)
>> val = (10.0 * val) + (s[i] - '0'); /* evaluate */
>>
>> if (s[i] == '.') ++i; /* skip the dot (.) of a floating point */
>>
>> for (power = 1.0; isdigit(s[i]); ++i) {
>> val = (10.0 * val) + (s[i] - '0'); /* eval post decimal */
>> power *= 10.0;
>> }
>> return sign * val / power;
>> }

>
> After (and tested, btw):
>
> double atof(char*s){int i=0,n=0;double v=0,p=
> 1;while(isspace(*s))++s;if(*s){n=(*s!='-')*2-
> 1;(*s=='+'||*s=='-')&&++s;while(isdigit(*s))v
> =(10.0*v)+(*s++-'0');if(*s=='.')while(isdigit
> (*++s))(v=10.*v+*s-'0'),p*=10;}return n*v/p;}
>
>> (this is one of my fetishes)

>
> Then presumably you are now doubly thrilled.

Well, Chuck's version is more readable than your _and_ more readable that
the OP's

Bye, Jojo


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
section with in a section config file and reading that config file kampy Python 9 10-19-2012 10:59 PM
K&R2 section 4.1 example arnuld C Programming 1 04-03-2008 11:05 AM
C++ Primer section 1.6 example arnuld C++ 1 07-13-2007 03:15 PM
Stroustrup ch2 section 2.3.2 example arnuld C++ 7 10-30-2006 06:51 PM
newbie question on Python tutorial example in section 4.7.1 (default arg values) Porky Pig Jr Python 5 05-03-2004 10:15 PM



Advertisments