Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

roots

3 views
Skip to first unread message

Bill Cunningham

unread,
Jun 25, 2009, 12:34:32 AM6/25/09
to
I have written a program that calculates powers or exponentiation but I
would like to write something that would give any root of any number. I know
this would involve factorials. Anyone have any hints? I don't want to use
the math.h header.

Bill


Keith Thompson

unread,
Jun 25, 2009, 1:02:37 AM6/25/09
to

Yeah, here are a couple of hints.

This will not involve factorials.

Use the math.h header.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

cr88192

unread,
Jun 25, 2009, 1:12:45 AM6/25/09
to

"Keith Thompson" <ks...@mib.org> wrote in message
news:lnhby4q...@nuthaus.mib.org...

> "Bill Cunningham" <nos...@nspam.invalid> writes:
>> I have written a program that calculates powers or
>> exponentiation but I would like to write something that would give
>> any root of any number. I know this would involve factorials. Anyone
>> have any hints? I don't want to use the math.h header.
>
> Yeah, here are a couple of hints.
>
> This will not involve factorials.
>
> Use the math.h header.
>

yep, otherwise one will just end up having to implement half the crap in
math.h manually, and poorly (AKA: slower and less reliable, partly because a
lot in math.h is actually compiler builtins which directly use facilities
provided by the CPU...).

Gordon Burditt

unread,
Jun 25, 2009, 2:25:54 AM6/25/09
to
> I have written a program that calculates powers or exponentiation but I
>would like to write something that would give any root of any number.

If you have a program that will calculate A**B for reals A and B
(** being the FORTRAN exponentiation operator used here because C
doesn't have one) then the Nth root of A is A**(1/N). But my guess
is that you haven't fully implemented your exponentiation function
to cover all cases (fractional and possibly irrational exponents,
negative values of A).

>I know
>this would involve factorials.

How do you know that?

>Anyone have any hints? I don't want to use
>the math.h header.

It won't involve factorials.

It will involve complex numbers (e.g. the square roots of -4 are +2i
and -2i ) and multiple results if you really mean "any root of any
(real) number".

Use the functions in the math.h header.

Nick Keighley

unread,
Jun 25, 2009, 3:39:52 AM6/25/09
to

do you know hoe to solve this problem with pencil and paper and a
calculator?

If you don't you won't be able to program it.

Paul

unread,
Jun 25, 2009, 7:42:52 AM6/25/09
to

"Bill Cunningham" <nos...@nspam.invalid> wrote in message
news:4a42fe6c$0$23738$bbae...@news.suddenlink.net...
No math.h, no factorials, but probably not much use.

#include <stdio.h>

int findroot(int root, int value)
{
int n;
int power = 0;
int test = 0;

while (power < value)
{
test++;

power = 1;

for (n = 0; n < root; n++)
{
power *= test;
}
}
return test;
}

int main(int argc, char **argv)
{
int n;
n = findroot(3,4913);
printf("number = %d\n", n);
return 0;
}

BartC

unread,
Jun 25, 2009, 8:04:26 AM6/25/09
to

"Bill Cunningham" <nos...@nspam.invalid> wrote in message
news:4a42fe6c$0$23738$bbae...@news.suddenlink.net...

To find the xth root of y, find the natural logarithm of y (say, using
Taylor series). Divide that by x. Then raise e to that power (another Taylor
series).

If y is negative and x is an integer, ignore the sign and multiply the
result by i (x is even) or -1 (x is odd). Take care when x and/or y are
zero.

Sorry I couldn't meaningfully involve factorials in this.

--
Bart

user923005

unread,
Jun 25, 2009, 1:25:35 PM6/25/09
to

If you include math.h then you can use something like this:

#include <math.h>
double root(double base, double root)
{
return pow(base, 1.0 / root);
}

int main(void)
{
double sqrt2 = root(2.0, 2.0);
double cbrt2 = root(2.0, 3.0);
double basev;
double rootv;

for (basev = 0.5; basev <= 10; basev += 0.5) {
for (rootv = 0.5; rootv <= 10; rootv += 0.5) {
printf("The %.2fth root of %.2f is %f\n",rootv, basev, root
(basev, rootv));
}
}
return 0;
}
/*
The 0.50th root of 0.50 is 0.250000
The 1.00th root of 0.50 is 0.500000
The 1.50th root of 0.50 is 0.629961
The 2.00th root of 0.50 is 0.707107
The 2.50th root of 0.50 is 0.757858
The 3.00th root of 0.50 is 0.793701
The 3.50th root of 0.50 is 0.820335
The 4.00th root of 0.50 is 0.840896
The 4.50th root of 0.50 is 0.857244
The 5.00th root of 0.50 is 0.870551
The 5.50th root of 0.50 is 0.881591
The 6.00th root of 0.50 is 0.890899
The 6.50th root of 0.50 is 0.898851
The 7.00th root of 0.50 is 0.905724
The 7.50th root of 0.50 is 0.911722
The 8.00th root of 0.50 is 0.917004
The 8.50th root of 0.50 is 0.921690
The 9.00th root of 0.50 is 0.925875
The 9.50th root of 0.50 is 0.929635
The 10.00th root of 0.50 is 0.933033
The 0.50th root of 1.00 is 1.000000
The 1.00th root of 1.00 is 1.000000
The 1.50th root of 1.00 is 1.000000
The 2.00th root of 1.00 is 1.000000
The 2.50th root of 1.00 is 1.000000
The 3.00th root of 1.00 is 1.000000
The 3.50th root of 1.00 is 1.000000
The 4.00th root of 1.00 is 1.000000
The 4.50th root of 1.00 is 1.000000
The 5.00th root of 1.00 is 1.000000
The 5.50th root of 1.00 is 1.000000
The 6.00th root of 1.00 is 1.000000
The 6.50th root of 1.00 is 1.000000
The 7.00th root of 1.00 is 1.000000
The 7.50th root of 1.00 is 1.000000
The 8.00th root of 1.00 is 1.000000
The 8.50th root of 1.00 is 1.000000
The 9.00th root of 1.00 is 1.000000
The 9.50th root of 1.00 is 1.000000
The 10.00th root of 1.00 is 1.000000
The 0.50th root of 1.50 is 2.250000
The 1.00th root of 1.50 is 1.500000
The 1.50th root of 1.50 is 1.310371
The 2.00th root of 1.50 is 1.224745
The 2.50th root of 1.50 is 1.176079
The 3.00th root of 1.50 is 1.144714
The 3.50th root of 1.50 is 1.122824
The 4.00th root of 1.50 is 1.106682
The 4.50th root of 1.50 is 1.094287
The 5.00th root of 1.50 is 1.084472
The 5.50th root of 1.50 is 1.076506
The 6.00th root of 1.50 is 1.069913
The 6.50th root of 1.50 is 1.064366
The 7.00th root of 1.50 is 1.059634
The 7.50th root of 1.50 is 1.055550
The 8.00th root of 1.50 is 1.051990
The 8.50th root of 1.50 is 1.048858
The 9.00th root of 1.50 is 1.046082
The 9.50th root of 1.50 is 1.043604
The 10.00th root of 1.50 is 1.041380
The 0.50th root of 2.00 is 4.000000
The 1.00th root of 2.00 is 2.000000
The 1.50th root of 2.00 is 1.587401
The 2.00th root of 2.00 is 1.414214
The 2.50th root of 2.00 is 1.319508
The 3.00th root of 2.00 is 1.259921
The 3.50th root of 2.00 is 1.219014
The 4.00th root of 2.00 is 1.189207
The 4.50th root of 2.00 is 1.166529
The 5.00th root of 2.00 is 1.148698
The 5.50th root of 2.00 is 1.134313
The 6.00th root of 2.00 is 1.122462
The 6.50th root of 2.00 is 1.112531
The 7.00th root of 2.00 is 1.104090
The 7.50th root of 2.00 is 1.096825
The 8.00th root of 2.00 is 1.090508
The 8.50th root of 2.00 is 1.084964
The 9.00th root of 2.00 is 1.080060
The 9.50th root of 2.00 is 1.075691
The 10.00th root of 2.00 is 1.071773
The 0.50th root of 2.50 is 6.250000
The 1.00th root of 2.50 is 2.500000
The 1.50th root of 2.50 is 1.842016
The 2.00th root of 2.50 is 1.581139
The 2.50th root of 2.50 is 1.442700
The 3.00th root of 2.50 is 1.357209
The 3.50th root of 2.50 is 1.299263
The 4.00th root of 2.50 is 1.257433
The 4.50th root of 2.50 is 1.225832
The 5.00th root of 2.50 is 1.201124
The 5.50th root of 2.50 is 1.181280
The 6.00th root of 2.50 is 1.164993
The 6.50th root of 2.50 is 1.151388
The 7.00th root of 2.50 is 1.139852
The 7.50th root of 2.50 is 1.129949
The 8.00th root of 2.50 is 1.121353
The 8.50th root of 2.50 is 1.113824
The 9.00th root of 2.50 is 1.107173
The 9.50th root of 2.50 is 1.101256
The 10.00th root of 2.50 is 1.095958
The 0.50th root of 3.00 is 9.000000
The 1.00th root of 3.00 is 3.000000
The 1.50th root of 3.00 is 2.080084
The 2.00th root of 3.00 is 1.732051
The 2.50th root of 3.00 is 1.551846
The 3.00th root of 3.00 is 1.442250
The 3.50th root of 3.00 is 1.368738
The 4.00th root of 3.00 is 1.316074
The 4.50th root of 3.00 is 1.276518
The 5.00th root of 3.00 is 1.245731
The 5.50th root of 3.00 is 1.221095
The 6.00th root of 3.00 is 1.200937
The 6.50th root of 3.00 is 1.184141
The 7.00th root of 3.00 is 1.169931
The 7.50th root of 3.00 is 1.157754
The 8.00th root of 3.00 is 1.147203
The 8.50th root of 3.00 is 1.137973
The 9.00th root of 3.00 is 1.129831
The 9.50th root of 3.00 is 1.122595
The 10.00th root of 3.00 is 1.116123
The 0.50th root of 3.50 is 12.250000
The 1.00th root of 3.50 is 3.500000
The 1.50th root of 3.50 is 2.305218
The 2.00th root of 3.50 is 1.870829
The 2.50th root of 3.50 is 1.650544
The 3.00th root of 3.50 is 1.518294
The 3.50th root of 3.50 is 1.430369
The 4.00th root of 3.50 is 1.367782
The 4.50th root of 3.50 is 1.321004
The 5.00th root of 3.50 is 1.284735
The 5.50th root of 3.50 is 1.255803
The 6.00th root of 3.50 is 1.232191
The 6.50th root of 3.50 is 1.212559
The 7.00th root of 3.50 is 1.195980
The 7.50th root of 3.50 is 1.181796
The 8.00th root of 3.50 is 1.169522
The 8.50th root of 3.50 is 1.158799
The 9.00th root of 3.50 is 1.149349
The 9.50th root of 3.50 is 1.140960
The 10.00th root of 3.50 is 1.133462
The 0.50th root of 4.00 is 16.000000
The 1.00th root of 4.00 is 4.000000
The 1.50th root of 4.00 is 2.519842
The 2.00th root of 4.00 is 2.000000
The 2.50th root of 4.00 is 1.741101
The 3.00th root of 4.00 is 1.587401
The 3.50th root of 4.00 is 1.485994
The 4.00th root of 4.00 is 1.414214
The 4.50th root of 4.00 is 1.360790
The 5.00th root of 4.00 is 1.319508
The 5.50th root of 4.00 is 1.286665
The 6.00th root of 4.00 is 1.259921
The 6.50th root of 4.00 is 1.237726
The 7.00th root of 4.00 is 1.219014
The 7.50th root of 4.00 is 1.203025
The 8.00th root of 4.00 is 1.189207
The 8.50th root of 4.00 is 1.177147
The 9.00th root of 4.00 is 1.166529
The 9.50th root of 4.00 is 1.157110
The 10.00th root of 4.00 is 1.148698
The 0.50th root of 4.50 is 20.250000
The 1.00th root of 4.50 is 4.500000
The 1.50th root of 4.50 is 2.725681
The 2.00th root of 4.50 is 2.121320
The 2.50th root of 4.50 is 1.825093
The 3.00th root of 4.50 is 1.650964
The 3.50th root of 4.50 is 1.536852
The 4.00th root of 4.50 is 1.456475
The 4.50th root of 4.50 is 1.396878
The 5.00th root of 4.50 is 1.350960
The 5.50th root of 4.50 is 1.314516
The 6.00th root of 4.50 is 1.284898
The 6.50th root of 4.50 is 1.260359
The 7.00th root of 4.50 is 1.239698
The 7.50th root of 4.50 is 1.222067
The 8.00th root of 4.50 is 1.206845
The 8.50th root of 4.50 is 1.193572
The 9.00th root of 4.50 is 1.181896
The 9.50th root of 4.50 is 1.171546
The 10.00th root of 4.50 is 1.162308
The 0.50th root of 5.00 is 25.000000
The 1.00th root of 5.00 is 5.000000
The 1.50th root of 5.00 is 2.924018
The 2.00th root of 5.00 is 2.236068
The 2.50th root of 5.00 is 1.903654
The 3.00th root of 5.00 is 1.709976
The 3.50th root of 5.00 is 1.583820
The 4.00th root of 5.00 is 1.495349
The 4.50th root of 5.00 is 1.429969
The 5.00th root of 5.00 is 1.379730
The 5.50th root of 5.00 is 1.339940
The 6.00th root of 5.00 is 1.307660
The 6.50th root of 5.00 is 1.280955
The 7.00th root of 5.00 is 1.258499
The 7.50th root of 5.00 is 1.239356
The 8.00th root of 5.00 is 1.222845
The 8.50th root of 5.00 is 1.208459
The 9.00th root of 5.00 is 1.195813
The 9.50th root of 5.00 is 1.184611
The 10.00th root of 5.00 is 1.174619
The 0.50th root of 5.50 is 30.250000
The 1.00th root of 5.50 is 5.500000
The 1.50th root of 5.50 is 3.115840
The 2.00th root of 5.50 is 2.345208
The 2.50th root of 5.50 is 1.977630
The 3.00th root of 5.50 is 1.765174
The 3.50th root of 5.50 is 1.627542
The 4.00th root of 5.50 is 1.531407
The 4.50th root of 5.50 is 1.460579
The 5.00th root of 5.50 is 1.406282
The 5.50th root of 5.50 is 1.363363
The 6.00th root of 5.50 is 1.328599
The 6.50th root of 5.50 is 1.299876
The 7.00th root of 5.50 is 1.275752
The 7.50th root of 5.50 is 1.255206
The 8.00th root of 5.50 is 1.237500
The 8.50th root of 5.50 is 1.222085
The 9.00th root of 5.50 is 1.208544
The 9.50th root of 5.50 is 1.196556
The 10.00th root of 5.50 is 1.185868
The 0.50th root of 6.00 is 36.000000
The 1.00th root of 6.00 is 6.000000
The 1.50th root of 6.00 is 3.301927
The 2.00th root of 6.00 is 2.449490
The 2.50th root of 6.00 is 2.047673
The 3.00th root of 6.00 is 1.817121
The 3.50th root of 6.00 is 1.668510
The 4.00th root of 6.00 is 1.565085
The 4.50th root of 6.00 is 1.489095
The 5.00th root of 6.00 is 1.430969
The 5.50th root of 6.00 is 1.385103
The 6.00th root of 6.00 is 1.348006
The 6.50th root of 6.00 is 1.317394
The 7.00th root of 6.00 is 1.291708
The 7.50th root of 6.00 is 1.269853
The 8.00th root of 6.00 is 1.251033
The 8.50th root of 6.00 is 1.234660
The 9.00th root of 6.00 is 1.220285
The 9.50th root of 6.00 is 1.207565
The 10.00th root of 6.00 is 1.196231
The 0.50th root of 6.50 is 42.250000
The 1.00th root of 6.50 is 6.500000
The 1.50th root of 6.50 is 3.482910
The 2.00th root of 6.50 is 2.549510
The 2.50th root of 6.50 is 2.114294
The 3.00th root of 6.50 is 1.866256
The 3.50th root of 6.50 is 1.707108
The 4.00th root of 6.50 is 1.596718
The 4.50th root of 6.50 is 1.515819
The 5.00th root of 6.50 is 1.454061
The 5.50th root of 6.50 is 1.405408
The 6.00th root of 6.50 is 1.366110
The 6.50th root of 6.50 is 1.333717
The 7.00th root of 6.50 is 1.306563
The 7.50th root of 6.50 is 1.283478
The 8.00th root of 6.50 is 1.263613
The 8.50th root of 6.50 is 1.246341
The 9.00th root of 6.50 is 1.231186
The 9.50th root of 6.50 is 1.217783
The 10.00th root of 6.50 is 1.205845
The 0.50th root of 7.00 is 49.000000
The 1.00th root of 7.00 is 7.000000
The 1.50th root of 7.00 is 3.659306
The 2.00th root of 7.00 is 2.645751
The 2.50th root of 7.00 is 2.177906
The 3.00th root of 7.00 is 1.912931
The 3.50th root of 7.00 is 1.743639
The 4.00th root of 7.00 is 1.626577
The 4.50th root of 7.00 is 1.540989
The 5.00th root of 7.00 is 1.475773
The 5.50th root of 7.00 is 1.424473
The 6.00th root of 7.00 is 1.383088
The 6.50th root of 7.00 is 1.349010
The 7.00th root of 7.00 is 1.320469
The 7.50th root of 7.00 is 1.296223
The 8.00th root of 7.00 is 1.275373
The 8.50th root of 7.00 is 1.257255
The 9.00th root of 7.00 is 1.241366
The 9.50th root of 7.00 is 1.227320
The 10.00th root of 7.00 is 1.214814
The 0.50th root of 7.50 is 56.250000
The 1.00th root of 7.50 is 7.500000
The 1.50th root of 7.50 is 3.831547
The 2.00th root of 7.50 is 2.738613
The 2.50th root of 7.50 is 2.238847
The 3.00th root of 7.50 is 1.957434
The 3.50th root of 7.50 is 1.778351
The 4.00th root of 7.50 is 1.654875
The 4.50th root of 7.50 is 1.564797
The 5.00th root of 7.50 is 1.496278
The 5.50th root of 7.50 is 1.442454
The 6.00th root of 7.50 is 1.399083
The 6.50th root of 7.50 is 1.363405
The 7.00th root of 7.50 is 1.333548
The 7.50th root of 7.50 is 1.308202
The 8.00th root of 7.50 is 1.286420
The 8.50th root of 7.50 is 1.267501
The 9.00th root of 7.50 is 1.250919
The 9.50th root of 7.50 is 1.236265
The 10.00th root of 7.50 is 1.223224
The 0.50th root of 8.00 is 64.000000
The 1.00th root of 8.00 is 8.000000
The 1.50th root of 8.00 is 4.000000
The 2.00th root of 8.00 is 2.828427
The 2.50th root of 8.00 is 2.297397
The 3.00th root of 8.00 is 2.000000
The 3.50th root of 8.00 is 1.811447
The 4.00th root of 8.00 is 1.681793
The 4.50th root of 8.00 is 1.587401
The 5.00th root of 8.00 is 1.515717
The 5.50th root of 8.00 is 1.459480
The 6.00th root of 8.00 is 1.414214
The 6.50th root of 8.00 is 1.377009
The 7.00th root of 8.00 is 1.345900
The 7.50th root of 8.00 is 1.319508
The 8.00th root of 8.00 is 1.296840
The 8.50th root of 8.00 is 1.277162
The 9.00th root of 8.00 is 1.259921
The 9.50th root of 8.00 is 1.244693
The 10.00th root of 8.00 is 1.231144
The 0.50th root of 8.50 is 72.250000
The 1.00th root of 8.50 is 8.500000
The 1.50th root of 8.50 is 4.164977
The 2.00th root of 8.50 is 2.915476
The 2.50th root of 8.50 is 2.353789
The 3.00th root of 8.50 is 2.040828
The 3.50th root of 8.50 is 1.843097
The 4.00th root of 8.50 is 1.707476
The 4.50th root of 8.50 is 1.608931
The 5.00th root of 8.50 is 1.534206
The 5.50th root of 8.50 is 1.475656
The 6.00th root of 8.50 is 1.428575
The 6.50th root of 8.50 is 1.389913
The 7.00th root of 8.50 is 1.357607
The 7.50th root of 8.50 is 1.330217
The 8.00th root of 8.50 is 1.306704
The 8.50th root of 8.50 is 1.286303
The 9.00th root of 8.50 is 1.268437
The 9.50th root of 8.50 is 1.252661
The 10.00th root of 8.50 is 1.238631
The 0.50th root of 9.00 is 81.000000
The 1.00th root of 9.00 is 9.000000
The 1.50th root of 9.00 is 4.326749
The 2.00th root of 9.00 is 3.000000
The 2.50th root of 9.00 is 2.408225
The 3.00th root of 9.00 is 2.080084
The 3.50th root of 9.00 is 1.873444
The 4.00th root of 9.00 is 1.732051
The 4.50th root of 9.00 is 1.629498
The 5.00th root of 9.00 is 1.551846
The 5.50th root of 9.00 is 1.491072
The 6.00th root of 9.00 is 1.442250
The 6.50th root of 9.00 is 1.402189
The 7.00th root of 9.00 is 1.368738
The 7.50th root of 9.00 is 1.340394
The 8.00th root of 9.00 is 1.316074
The 8.50th root of 9.00 is 1.294982
The 9.00th root of 9.00 is 1.276518
The 9.50th root of 9.00 is 1.260221
The 10.00th root of 9.00 is 1.245731
The 0.50th root of 9.50 is 90.250000
The 1.00th root of 9.50 is 9.500000
The 1.50th root of 9.50 is 4.485550
The 2.00th root of 9.50 is 3.082207
The 2.50th root of 9.50 is 2.460874
The 3.00th root of 9.50 is 2.117912
The 3.50th root of 9.50 is 1.902609
The 4.00th root of 9.50 is 1.755622
The 4.50th root of 9.50 is 1.649195
The 5.00th root of 9.50 is 1.568717
The 5.50th root of 9.50 is 1.505802
The 6.00th root of 9.50 is 1.455305
The 6.50th root of 9.50 is 1.413901
The 7.00th root of 9.50 is 1.379351
The 7.50th root of 9.50 is 1.350091
The 8.00th root of 9.50 is 1.324999
The 8.50th root of 9.50 is 1.303246
The 9.00th root of 9.50 is 1.284210
The 9.50th root of 9.50 is 1.267413
The 10.00th root of 9.50 is 1.252485
The 0.50th root of 10.00 is 100.000000
The 1.00th root of 10.00 is 10.000000
The 1.50th root of 10.00 is 4.641589
The 2.00th root of 10.00 is 3.162278
The 2.50th root of 10.00 is 2.511886
The 3.00th root of 10.00 is 2.154435
The 3.50th root of 10.00 is 1.930698
The 4.00th root of 10.00 is 1.778279
The 4.50th root of 10.00 is 1.668101
The 5.00th root of 10.00 is 1.584893
The 5.50th root of 10.00 is 1.519911
The 6.00th root of 10.00 is 1.467799
The 6.50th root of 10.00 is 1.425103
The 7.00th root of 10.00 is 1.389495
The 7.50th root of 10.00 is 1.359356
The 8.00th root of 10.00 is 1.333521
The 8.50th root of 10.00 is 1.311134
The 9.00th root of 10.00 is 1.291550
The 9.50th root of 10.00 is 1.274275
The 10.00th root of 10.00 is 1.258925
*/

Bill Cunningham

unread,
Jun 25, 2009, 5:33:17 PM6/25/09
to

"Gordon Burditt" <gordon...@burditt.org> wrote in message
news:z5GdnbRThazvhd7X...@posted.internetamerica...

>> I have written a program that calculates powers or exponentiation but
>> I
>>would like to write something that would give any root of any number.
>
> If you have a program that will calculate A**B for reals A and B
> (** being the FORTRAN exponentiation operator used here because C
> doesn't have one) then the Nth root of A is A**(1/N). But my guess
> is that you haven't fully implemented your exponentiation function
> to cover all cases (fractional and possibly irrational exponents,
> negative values of A).
>
>>I know
>>this would involve factorials.
>
> How do you know that?

Sorry my mistake. I was thinking about combinations and permutations.

Bill Cunningham

unread,
Jun 25, 2009, 5:34:48 PM6/25/09
to

"Nick Keighley" <nick_keigh...@hotmail.com> wrote in message
news:c9d4f97f-2414-420d...@j9g2000vbp.googlegroups.com...

do you know hoe to solve this problem with pencil and paper and a
calculator?

If you don't you won't be able to program it.

There's a way to use fractions with roots to get the roots of numbers.
Now if the pow() functions would take this hopefully without a cast.

Bill


Bill Cunningham

unread,
Jun 25, 2009, 5:38:29 PM6/25/09
to

"BartC" <ba...@freeuk.com> wrote in message
news:eJJ0m.47375$OO7....@text.news.virginmedia.com...

> Sorry I couldn't meaningfully involve factorials in this.
>

Oops I was thinking about combinations and permutations. Fractions can
be used to do this with paper and calculator. I might be able to get log()
or pow() to work using the fractions that are involved with roots.

Bill


Keith Thompson

unread,
Jun 25, 2009, 5:52:41 PM6/25/09
to

You're on the right track.

pete

unread,
Jun 25, 2009, 6:32:05 PM6/25/09
to


(sqrt(2) == pow(2, 0.5))


--
pete

Mark McIntyre

unread,
Jun 25, 2009, 6:56:45 PM6/25/09
to

Bill, this isn't a C question. Work out the algorithm first, perhaps by
reading some maths books, and then try to write the code. If you get
stuck with the code, people can probably help.

pete

unread,
Jun 25, 2009, 8:28:00 PM6/25/09
to
user923005 wrote:
> On Jun 24, 9:34 pm, "Bill Cunningham" <nos...@nspam.invalid> wrote:
>> I have written a program that calculates powers or exponentiation but I
>> would like to write something that would give any root of any number. I know
>> this would involve factorials. Anyone have any hints? I don't want to use
>> the math.h header.
>
> If you include math.h then you can use something like this:
>
> #include <math.h>
> double root(double base, double root)
> {
> return pow(base, 1.0 / root);
> }

And you can write a power function without math.h;
but I needed about a year of calculus
before I could understand the Taylor series
that I used when I wrote one.

--
pete

user923005

unread,
Jun 26, 2009, 1:01:14 AM6/26/09
to
On Jun 25, 3:32 pm, pete <pfil...@mindspring.com> wrote:
> Bill Cunningham wrote:
> > "Nick Keighley" <nick_keighley_nos...@hotmail.com> wrote in message

> >news:c9d4f97f-2414-420d...@j9g2000vbp.googlegroups.com...
>
> > do you know hoe to solve this problem with pencil and paper and a
> > calculator?
>
> > If you don't you won't be able to program it.
>
> >     There's a way to use fractions with roots to get the roots of numbers.
> > Now if the pow() functions would take this hopefully without a cast.
>
> (sqrt(2) == pow(2, 0.5))

Or perhaps more simply:
sqrt(2.0) == pow(2.0, 1.0/2.0);

cbrt(2.0) == pow(2.0, 1.0/3.0);

Fourth root of 2:
pow(2.0, 1.0/4.0);

nth root of 2:
pow(2.0, 1.0/N);

Kaz Kylheku

unread,
Jun 26, 2009, 1:29:39 AM6/26/09
to

It doesn't have to involve factorials. If you restrict yourself to positive,
integral roots (like the square root, cube root, 4-th root, 5-th, etc)
of positive real numbers, you can do this using Newton's method.

The n-th root of a postive number m is a solution to the equation

f(x) = 0

Where
n
f(x) = x - m

For Newton's method, we need the derivative of f:

n-1
f'(x) = n x

Newton's method means we start with some guess value, call it g.

We evaluate f(g) and if it's close enough to zero, we conclude that g is the
root.

If f(g) is not close to zero, we refine our guess using this formula:

g - f(g)/f'(g)

this value is installed as the new value of g, with which we try again.

There is a geometric reason for choosing this guess value. Newton's method
works by finding a tangent line to the function at f(g). This line shoots
toward the x axis, and where it crosses, that's where the next guess is found.
I.e. a better guess at the root is found by approximating the function using
a straight line that passes through the point <g, f(g)> and which has
the same slope as that function. The root of this straight line is found,
and substituted as the next guess. Then the process is repeated.

Look it up on Wikipedia for a better description with graphics.

Here is a toy program with no error checking and poor numerical analysis
which will take two command line arguments: a positive integer specifying which
root to take, and a positive number, whose root to compute. There is no bound
on the number of iterations, and the choice m/2 for the starting guess is
questionable.

We avoid using <math.h> by implementing a simple power function that just
multiples a number together multiple times (handling non-negative integer
powers only). Also, for the same reason of avoiding <math.h>, we avoid using
fabs for the termination test, but instead check our intermediate f(g) value
against two bounds.

#include <stdio.h>
#include <stdlib.h>

#define CLOSE_ENOUGH 0.0000001

/*
* Raise x to the non-negative integral power n.
*/
double intpow(double x, int n)
{
if (n == 0) {
return 1.0;
} else {
int i;
double accum = x;

for (i = 1; i < n; i++)
accum *= x;

return accum;
}
}

/* n
* Evaluate the function f(x; n, m) = x - m
*/
double f(double x, int n, double m)
{
return intpow(x, n) - m;
}

/* n - 1
* Evaluate the function f'(x; n) = n * x
*/
double df(double x, int n)
{
return intpow(x, n - 1) * n;
}

int main(int argc, char **argv)
{
int n;

double m, g;

if (argc < 3) {
if (argv[0]) {
printf("usage: %s n m\n", argv[0]);
printf("n is a small positive integer\n");
printf("m is a positive real number\n");
}
return EXIT_FAILURE;
}

/*
* TODO: check inputs!
* - junk data
* - non-positive n
* - negative m.
*/

n = atoi(argv[1]);
m = atof(argv[2]);

/*
* Exercise: find a better initial guess strategy.
*/
g = m / 2;

for (;;) {
double fg = f(g, n, m);

printf("guess = %g\n", g);

if (fg - 0 > -CLOSE_ENOUGH && fg < CLOSE_ENOUGH) {
printf("approximate %d root of %g = %g\n", n, m, g);
break;
}

g = g - fg/df(g, n);
}
}

Sample runs:

$ ./newton 3 8
guess = 4
guess = 2.83333
guess = 2.22107
guess = 2.02127
guess = 2.00022
guess = 2
guess = 2
approximate 3 root of 8 = 2

$ ./newton 3 27
guess = 13.5
guess = 9.04938
guess = 6.14282
guess = 4.33373
guess = 3.36835
guess = 3.03881
guess = 3.00049
guess = 3
guess = 3
approximate 3 root of 27 = 3

$ ./newton 2 5
guess = 2.5
guess = 2.25
guess = 2.23611
guess = 2.23607
approximate 2 root of 5 = 2.23607

$ ./newton 3 5
guess = 2.5
guess = 1.93333
guess = 1.73479
guess = 1.71033
guess = 1.70998
guess = 1.70998
approximate 3 root of 5 = 1.70998

Phil Carmody

unread,
Jun 26, 2009, 1:47:49 AM6/26/09
to

Fortunately CORDIC's pretty trivial for log and exp, so no need
for Taylor/MacLaurin series, or any in-depth knowledge of calculus.
All you need to know is that exp(a+b)=exp(a)*exp(b) and log(a*b)=
log(a)+log(b).

Phil
--
Marijuana is indeed a dangerous drug.
It causes governments to wage war against their own people.
-- Dave Seaman (sci.math, 19 Mar 2009)

robert...@yahoo.com

unread,
Jun 26, 2009, 6:56:37 PM6/26/09
to


Technically speaking evaluating a Taylor series involves some
factorials.

More seriously, I'd point out that the method you've described, while
mathematically correct, leads to pretty poor results in real
implementations without a *lot* of extra work. You lose a lot of
precision right up front since the log() function basically shoves the
entire exponent into the mantissa (and pushing that much of the
exponent off the bottom). In practical terms, the straight-forward
implementation of the algorithm you described, using IEEE doubles,
will probably net less than 35 bits of meaningful precision. General
exponentiation (eg. pow(x,y) ) is a seriously hard function to
implement well.

user923005

unread,
Jun 26, 2009, 7:48:36 PM6/26/09
to
On Jun 26, 3:56 pm, "robertwess...@yahoo.com"

The simplest way to solve a problem like this is to use the existing C
math library.

Assuming that the problem is due to some partial implementation (e.g.
an oddball compiler for programming IC's or the like) that lacks the
pow() function, then open source implementations like the Cephes
collection by Moshier make sense.
For instance, for computation of real valued powers and roots, we have
these functions for various precisions:

Float:
extern float exp10f(float xx);
extern float exp2f(float xx);
extern float expf(float xx);
extern float expnf(int n,float xx);
extern float log10f(float xx);
extern float log2f(float xx);
extern float logf(float xx);
extern float powf(float x,float y);
extern float powif(float x,int nn);

Double:
extern double exp(double x);
extern double exp10(double x);
extern double exp2(double x);
extern double expm1(double x);
extern double expn(int n,double x);
extern double log(double x);
extern double log10(double x);
extern double log1p(double x);
extern double log2(double x);
extern double pow(double x,double y);
extern double powi(double x,int nn);

Long double:
extern long double exp10l(long double x);
extern long double exp2l(long double x);
extern long double expl(long double x);
extern long double ldexpl(long double x,int pw2);
extern long double log10l(long double x);
extern long double log1pl(long double x);
extern long double log2l(long double x);
extern long double logl(long double x);
extern long double powil(long double x,int nn);
extern long double powl(long double x,long double y);

Extended precision:
extern int qexp(unsigned int *x,unsigned int *y);
extern int qexp10(unsigned int *x,unsigned int *y);
extern int qexp11(unsigned int *xx,unsigned int *y);
extern int qexp2(unsigned int *x,unsigned int *y);
extern int qexpn(int n,unsigned int *x,unsigned int *yy);
extern int qlog(unsigned int *x,unsigned int *y);
extern int qlog1(unsigned int *x,unsigned int *y);
extern int qlog10(unsigned int *x,unsigned int *y);
extern int qlogtwo(unsigned int *x,unsigned int *y);
extern int qpow(unsigned int *x,unsigned int *y,unsigned int *z);
extern int qpowi(unsigned int *x,unsigned int *y,unsigned int *z);

BartC

unread,
Jun 26, 2009, 8:21:44 PM6/26/09
to
robert...@yahoo.com wrote:
> On Jun 25, 7:04 am, "BartC" <ba...@freeuk.com> wrote:
>> "Bill Cunningham" <nos...@nspam.invalid> wrote in message
>>
>> news:4a42fe6c$0$23738$bbae...@news.suddenlink.net...
>>
>>> I have written a program that calculates powers or exponentiation
>>> but I would like to write something that would give any root of any
>>> number. I know this would involve factorials. Anyone have any
>>> hints? I don't want to use the math.h header.
>>
>> To find the xth root of y, find the natural logarithm of y (say,
>> using Taylor series). Divide that by x. Then raise e to that power
>> (another Taylor series).
>>
>> If y is negative and x is an integer, ignore the sign and multiply
>> the result by i (x is even) or -1 (x is odd). Take care when x
>> and/or y are zero.
>>
>> Sorry I couldn't meaningfully involve factorials in this.
>
>
> Technically speaking evaluating a Taylor series involves some
> factorials.

Yes of course. Except I haven't looked at one for years.

> More seriously, I'd point out that the method you've described, while
> mathematically correct, leads to pretty poor results in real
> implementations without a *lot* of extra work. You lose a lot of
> precision right up front since the log() function basically shoves the
> entire exponent into the mantissa (and pushing that much of the
> exponent off the bottom). In practical terms, the straight-forward
> implementation of the algorithm you described, using IEEE doubles,
> will probably net less than 35 bits of meaningful precision. General
> exponentiation (eg. pow(x,y) ) is a seriously hard function to
> implement well.

I've just had a quick go and found that 16 terms are enough for 6 decimals
of a natural log, and 8 terms for 6 decimals of an exponential function (OK,
within a narrow input range). That's better than the 5-figure log tables I
was using at school.

(And the 5th root of 0.5 came out as 0.870551, in accordance with
user923005's post.)

So these series could still be a viable way of calculating these functions
with basic arithmetic.

--
Bart

Bill Cunningham

unread,
Jun 26, 2009, 8:29:42 PM6/26/09
to

"user923005" <dco...@connx.com> wrote in message
news:0f9932cd-e5a6-48b4...@d34g2000prb.googlegroups.com...

> (sqrt(2) == pow(2, 0.5))

Or perhaps more simply:
sqrt(2.0) == pow(2.0, 1.0/2.0);

cbrt(2.0) == pow(2.0, 1.0/3.0);

Fourth root of 2:
pow(2.0, 1.0/4.0);

nth root of 2:
pow(2.0, 1.0/N);

This code below seems to work pretty good.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char **argv)
{

double root, base, ans;
if (argc != 3) {
fputs("root usage error\n base root\n", stderr);
exit(EXIT_FAILURE);
}
root = strtod(argv[2], NULL);
base = strtod(argv[1], NULL);
ans = pow(base, 1.0 / root);
printf("%.2f\n", ans);
return 0;
}

user923005

unread,
Jun 26, 2009, 8:34:13 PM6/26/09
to
On Jun 26, 5:21 pm, "BartC" <ba...@freeuk.com> wrote:

You must be careful about conclusions based on a few data points.
For instance, Newton's method converges slowly near multiple roots.
A Taylor series will quickly get terrible results as you move away
from the locus.
Numerical calculations can be quite fiddly, especially if you want to
get within 1/2 ULP.
So if it is possible, it is best to go with an already programmed and
tested solution.

Besides Cephes, there is also this:
http://lipforge.ens-lyon.fr/projects/crlibm/

and many others.

I can't think of a sensible reason why someone would need to write
their own sqrt(), pow() or log() {for instance} other than for fun.

osmium

unread,
Jun 26, 2009, 8:43:01 PM6/26/09
to
"Bill Cunningham" wrote:

> This code below seems to work pretty good.
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <math.h>
>
> int main(int argc, char **argv)
> {
> double root, base, ans;
> if (argc != 3) {
> fputs("root usage error\n base root\n", stderr);
> exit(EXIT_FAILURE);
> }
> root = strtod(argv[2], NULL);
> base = strtod(argv[1], NULL);
> ans = pow(base, 1.0 / root);
> printf("%.2f\n", ans);
> return 0;
> }

But it has nothing to do with this thread! The OP said:

> I don't want to use the math.h header.

The code above violates that essential requirement.



pete

unread,
Jun 26, 2009, 10:29:51 PM6/26/09
to

That was the first step.
Now all that he has left to do,
is to implement his own version of pow.

--
pete

robert...@yahoo.com

unread,
Jun 27, 2009, 2:27:23 AM6/27/09
to
On Jun 26, 7:21 pm, "BartC" <ba...@freeuk.com> wrote:


To expand on what user923005 wrote, computing pow(x,y) as using Taylor
series to evaluate exp(y*ln(x)) certainly works to some extent. And
it's not even all that hard to implement, especially if you can keep
the ranges down and avoid many of the special cases. Some range
reductions are not that hard either to keep the operands in the ranges
where the series converge well. But even the simple solution is a
fair chunk of code. The problem is that the result is not
particularly accurate because of the limitations of floating point
arithmetic. As I mentioned, you'd likely get about 35 bits of useful
precision doing this with doubles - which is a far cry from the 52* or
so I'd expect from a competent implementation of pow(x,y). And it's
hard to do better while still performing well (for example, you could
do the calculations using software implemented quad precision floats,
and the basic algorithm stays simple, but you'll take a big
performance hit).

But that may very well be good enough for the application in
question. Further the application might restrict the ranges of the
inputs, not care about the myriad of special cases, etc., all of which
might allow you to implement something much simpler than a "full
function" and "high performance" pow(x,y).

FWIW, this question came up a few years ago in the context of speeding
up an inner loop in a graphics operation using SIMD (x86 SSE)
instructions, and I sketched out a solution using basically the simple
approach, but with singles instead of doubles. I estimated that the
code would produce about 17 bits of useful precision (rather less than
the 23* or so I'd expect from a "good" implementation). While doing
four pow()'s in parallel adds some complexity, it wasn't that much,
and I didn’t handle any of the special cases. All told this took
about 169 instructions, and 692 precomputed single precision
constants, and did some tricky stuff with the IEEE singles at the bit
level (while leaving a bunch of stuff out).

The post with the code discusses many of the issues in rather more
detail:

http://groups.google.com/group/comp.lang.asm.x86/msg/648520043d996528?hl=en

Again, the question is what exactly the requirements of the
application are - but implement a general pow(x,y) well is *hard*.


*That's allowing an error of a couple of ULPs for a "good"
implementation - a great implementation will limit the error to a
single ULP.

user923005

unread,
Jun 27, 2009, 4:48:33 AM6/27/09
to

1. The person you are objecting to is the OP
2. The OP is "Bill Cunningham" so we read between the lines.

BartC

unread,
Jun 27, 2009, 8:35:52 AM6/27/09
to
robert...@yahoo.com wrote:
> On Jun 26, 7:21 pm, "BartC" <ba...@freeuk.com> wrote:
>> robertwess...@yahoo.com wrote:
>>> On Jun 25, 7:04 am, "BartC" <ba...@freeuk.com> wrote:
>>>> "Bill Cunningham" <nos...@nspam.invalid> wrote in message
>>>> news:4a42fe6c$0$23738$bbae...@news.suddenlink.net...
>>
>>>>> I have written a program that calculates powers or exponentiation
>>>>> but I would like to write something that would give any root of
>>>>> any number. I know this would involve factorials. Anyone have any
>>>>> hints? I don't want to use the math.h header.
>>
>>>> To find the xth root of y, find the natural logarithm of y (say,
>>>> using Taylor series). Divide that by x. Then raise e to that power
>>>> (another Taylor series).

>>> More seriously, I'd point out that the method you've described,


>>> while mathematically correct, leads to pretty poor results in real
>>> implementations without a *lot* of extra work.

>>


>> I've just had a quick go and found that 16 terms are enough for 6
>> decimals of a natural log, and 8 terms for 6 decimals of an
>> exponential function (OK, within a narrow input range). That's
>> better than the 5-figure log tables I was using at school.

> To expand on what user923005 wrote, computing pow(x,y) as using Taylor


> series to evaluate exp(y*ln(x)) certainly works to some extent. And
> it's not even all that hard to implement, especially if you can keep
> the ranges down and avoid many of the special cases.

> FWIW, this question came up a few years ago in the context of speeding


> up an inner loop in a graphics operation using SIMD (x86 SSE)
> instructions, and I sketched out a solution using basically the simple
> approach, but with singles instead of doubles.

> http://groups.google.com/group/comp.lang.asm.x86/msg/648520043d996528?hl=en

So you seemed to be using Taylor series as well...

That thread seemed partly to be about calculating gamma values for image
data. That's one of the least demanding applications, both in precision and
speed: you only have to map an 8-bit value to another, and usually you
create a lookup table to do the mapping.

That means calculating to 8-bits and doing 256 power calculations (or
possibly 12-bits and 4096) (which are then applied millions of times).

> Again, the question is what exactly the requirements of the
> application are - but implement a general pow(x,y) well is *hard*.

If you're familiar with the OP then you'll know that by tomorrow he'll be
onto something entirely different.

--
Bart

osmium

unread,
Jun 27, 2009, 9:52:37 AM6/27/09
to
user923005 wrote:

> "osmium" wrote:

Well, fer gosh sakes!


Paul N

unread,
Jun 27, 2009, 2:37:20 PM6/27/09
to
On 25 June, 23:32, pete <pfil...@mindspring.com> wrote:

> (sqrt(2) == pow(2, 0.5))

Is it just me, or do other people think it is silly that pow(2, 1/2)
doesn't calculate the square root of two? The compiler *knows* that
pow takes two doubles, but it presists in messing up the calculation
first and coverting it to a double later. I haven't thought though all
the consequences of a change, but it seems daft the way things stand.
Grr.

osmium

unread,
Jun 27, 2009, 2:48:24 PM6/27/09
to
"Paul N" wrote:

>> (sqrt(2) == pow(2, 0.5))
>
> Is it just me, or do other people think it is silly that pow(2, 1/2)
> doesn't calculate the square root of two? The compiler *knows* that
> pow takes two doubles, but it presists in messing up the calculation
> first and coverting it to a double later. I haven't thought though all
> the consequences of a change, but it seems daft the way things stand.
> Grr.

I don't think you have really thought this through very far. For starters,
the caller and the callee are separate things, never the twain shall meet
and all that.


BartC

unread,
Jun 27, 2009, 3:21:40 PM6/27/09
to

"Paul N" <gw7...@aol.com> wrote in message
news:ec612fad-6737-4a64...@h28g2000yqd.googlegroups.com...

C just has the single operator for division. Some languages have separate
division ops for floats and integers.

So you will get this sort of ambiguity sometimes.

Doing things your way, part from not being practical to change now, has it's
own problems; suppose all these other names are ints:

int i = ((a/b+c)*(d+e)-(f+g/h));
float x = ((a/b+c)*(d+e)-(f+g/h));
float y = i;

In the second line, the float conversion has to propagate all the way down,
likely giving a completely different, and unintended, result, ie. i != x and
x != y;

--
Bartc

Gordon Burditt

unread,
Jun 27, 2009, 4:19:32 PM6/27/09
to
>Is it just me, or do other people think it is silly that pow(2, 1/2)
>doesn't calculate the square root of two?

It seems silly to make the result and/or type of the / operator
depend on what the result is used for. That's a disaster waiting
to happen, especially in macros. If the second argument is a
constant 0.5, you should be using sqrt().

Be careful what you ask for and how you ask for it, you might get it.
I'm curious how you'd change the rules so that:
pow(2, 1/2)
calculates the square root of 2 but
pow(2, ((int)1)/(int) 2)
doesn't. It would be really wierd having to cast an integer constant
to type int in order to have it treated as int.
I suppose your change would also apply to:
d = l1 / l2;
where d is a double and l1 and l2 are two longs. That's a problem
waiting to happen, as it may occur in code carefully written to
do integer division in the appropriate way. Beware, also, that l1
and l2 might not be convertable to double without rounding error.

If you're serious about fixing this "problem", I suggest a new
always-floating-point division operator: ~/~ (It looks like the
/ is floating in the ocean). I don't believe this can occur in
currently-legal C (outside of comments and character and string
constants, where that sequence would not be interpreted as an
operator).

Now fix your expression to:
pow(2, 1~/~2);


pete

unread,
Jun 27, 2009, 7:21:43 PM6/27/09
to
> and I didn�t handle any of the special cases. All told this took

> about 169 instructions, and 692 precomputed single precision
> constants, and did some tricky stuff with the IEEE singles at the bit
> level (while leaving a bunch of stuff out).
>
> The post with the code discusses many of the issues in rather more
> detail:
>
> http://groups.google.com/group/comp.lang.asm.x86/msg/648520043d996528?hl=en
>
> Again, the question is what exactly the requirements of the
> application are - but implement a general pow(x,y) well is *hard*.
>
>
> *That's allowing an error of a couple of ULPs for a "good"
> implementation - a great implementation will limit the error to a
> single ULP.

fs_pow is my homade pow function.

It is here
http://www.mindspring.com/~pfilandr/C/fs_math/

I can get this line
printf("fs_pow(1.0 / 1000, 1.0 / -3) - 10 is %e\n",
fs_pow(1.0 / 1000, 1.0 / -3) - 10);

to print this output
fs_pow(1.0 / 1000, 1.0 / -3) - 10 is 3.552714e-015

which isn't as good as
pow(1.0 / 1000, 1.0 / -3) - 10 is -1.776357e-015
for the standard library pow function
on the implementation that I'm using,
but it's not too bad, for academic code.

--
pete

Keith Thompson

unread,
Jun 27, 2009, 7:45:47 PM6/27/09
to

You just have to keep in mind that, in most cases, the type and result
of an expression are determined by the expression itself, regardless
of its context. So 1/2 yields the value 0 of type int. It actually
makes the language simpler to describe and understand than a more
complex set of rules would be, even if it sometimes yields admittedly
counterintuitive results.

Phil Carmody

unread,
Jun 28, 2009, 1:27:39 AM6/28/09
to
gordon...@burditt.org (Gordon Burditt) writes:

>>Is it just me, or do other people think it is silly that pow(2, 1/2)
>>doesn't calculate the square root of two?
>
> It seems silly to make the result and/or type of the / operator
> depend on what the result is used for.

Some languages do it. In those, it's not silly at all.

> That's a disaster waiting
> to happen, especially in macros.

Maybe macros are a disaster waiting to happen?

James Dow Allen

unread,
Jun 28, 2009, 2:57:02 AM6/28/09
to
On Jun 28, 1:37 am, Paul N <gw7...@aol.com> wrote:
> Is it just me, or do other people think it is silly that pow(2, 1/2)
> doesn't calculate the square root of two? The compiler *knows* ...

Is it just me, or do others agree that the compiler
should place bar() in the if scope in
if (Pred)
foo(); bar();
The compiler can see how I indented.

Is it just me, or do others think it's silly the
compiler doesn't replace "<" with "<=" when it
can figure out the logic requires the latter?

Is it just me, or do others agree the compiler
should replace "%d" with "%f" when I've used the
wrong one in a printf()? The compiler knows the
types of the args.

Is it just me, or do others agree the compiler
should dial Rent-a-Coder automatically when I've
made more than 7 errors?

Is it just me?

James Dow Allen

Nobody

unread,
Jun 28, 2009, 3:19:39 AM6/28/09
to
On Sat, 27 Jun 2009 11:37:20 -0700, Paul N wrote:

> On 25 June, 23:32, pete <pfil...@mindspring.com> wrote:
>
>> (sqrt(2) == pow(2, 0.5))
>
> Is it just me, or do other people think it is silly that pow(2, 1/2)
> doesn't calculate the square root of two?

It's just you.

> The compiler *knows* that
> pow takes two doubles, but it presists in messing up the calculation
> first and coverting it to a double later.

Them's the rules of the language. 1/2 is an integer division, regardless
of what you do with the result.

> I haven't thought though all
> the consequences of a change, but it seems daft the way things stand.
> Grr.

The main consequence of a change is that the language would become
incomprehensible.

C's type coercion rules are simple and therefore easy to remember, and
it's simple to force specific coercions as required.

Having type coercions propagate from top to bottom would be a nuisance for
non-trivial expressions, and with no real benefit (do you genuinely have
trouble remembering that 1/2 is zero, not 0.5?)

BartC

unread,
Jun 28, 2009, 5:21:40 AM6/28/09
to

"Nobody" <nob...@nowhere.com> wrote in message
news:pan.2009.06.28....@nowhere.com...

> On Sat, 27 Jun 2009 11:37:20 -0700, Paul N wrote:
>
>> On 25 June, 23:32, pete <pfil...@mindspring.com> wrote:
>>
>>> (sqrt(2) == pow(2, 0.5))
>>
>> Is it just me, or do other people think it is silly that pow(2, 1/2)
>> doesn't calculate the square root of two?

> Having type coercions propagate from top to bottom would be a nuisance for


> non-trivial expressions, and with no real benefit (do you genuinely have
> trouble remembering that 1/2 is zero, not 0.5?)

He has a point: just about everywhere else on the planet (or even in the
universe), 1/2 is a half. And here:

a=1;
b=2;

it's not immediately clear whether a/b is going to be a half, or zero. The
argument for having a separate integer division operator is quite good.

--
Bart

Keith Thompson

unread,
Jun 28, 2009, 1:13:22 PM6/28/09
to

Of course, changing the meaning of "/" in C and breaking existing code
is not an option.

Nobody

unread,
Jun 28, 2009, 4:43:32 PM6/28/09
to
On Sun, 28 Jun 2009 10:13:22 -0700, Keith Thompson wrote:

> Of course, changing the meaning of "/" in C and breaking existing code
> is not an option.

OTOH, doing the same thing in Python is fine, apparently.

In 2.x, int/int is an integer division; in 3.x, it's floating-point. You
can use // in either version to force integer division.

Nick Keighley

unread,
Jun 29, 2009, 3:26:46 AM6/29/09
to
On 28 June, 06:27, Phil Carmody <thefatphil_demun...@yahoo.co.uk>
wrote:
> gordonb.34...@burditt.org (Gordon Burditt) writes:

> >>Is it just me, or do other people think it is silly that pow(2, 1/2)
> >>doesn't calculate the square root of two?
>
> > It seems silly to make the result and/or type of the / operator
> > depend on what the result is used for.
>
> Some languages do it. In those, it's not silly at all.

for instance?

>
> > That's a disaster waiting
> > to happen, especially in macros.
>
> Maybe macros are a disaster waiting to happen?

could well be!

Phil Carmody

unread,
Jun 29, 2009, 3:58:22 AM6/29/09
to
Nick Keighley <nick_keigh...@hotmail.com> writes:
> On 28 June, 06:27, Phil Carmody <thefatphil_demun...@yahoo.co.uk>
> wrote:
>> gordonb.34...@burditt.org (Gordon Burditt) writes:
>
>> >>Is it just me, or do other people think it is silly that pow(2, 1/2)
>> >>doesn't calculate the square root of two?
>>
>> > It seems silly to make the result and/or type of the / operator
>> > depend on what the result is used for.
>>
>> Some languages do it. In those, it's not silly at all.
>
> for instance?

I see I could have been misinterpreted. I wasn't thinking
specifically of the / operator, but of functions in general.
Perl has the ability for any function to know whether it is
expected to return an value of array type or scalar type.

>> > That's a disaster waiting
>> > to happen, especially in macros.
>>
>> Maybe macros are a disaster waiting to happen?
>
> could well be!

Ah, that reminds me, I should be at work fixing Coverity and
style issues to do with macros...

Richard Bos

unread,
Jul 5, 2009, 7:31:56 AM7/5/09
to
"BartC" <ba...@freeuk.com> wrote:

> "Nobody" <nob...@nowhere.com> wrote in message

> > On Sat, 27 Jun 2009 11:37:20 -0700, Paul N wrote:
> >> On 25 June, 23:32, pete <pfil...@mindspring.com> wrote:
> >>
> >>> (sqrt(2) == pow(2, 0.5))
> >>
> >> Is it just me, or do other people think it is silly that pow(2, 1/2)
> >> doesn't calculate the square root of two?
>
> > Having type coercions propagate from top to bottom would be a nuisance for
> > non-trivial expressions, and with no real benefit (do you genuinely have
> > trouble remembering that 1/2 is zero, not 0.5?)
>
> He has a point: just about everywhere else on the planet (or even in the
> universe), 1/2 is a half.

Anywhere except inside computers. Most C code runs on computers, and
most computers truncate integer divisions. It should be surprising to a
greengrocer that 1/2 evaluates to 0, but not to a programmer.

> And here:
>
> a=1;
> b=2;
>
> it's not immediately clear whether a/b is going to be a half, or zero. The
> argument for having a separate integer division operator is quite good.

There are languages which have it. The problem is, where do you stop?
Integer division? Unsigned subtraction? Pointer comparison?

Richard

Phil Carmody

unread,
Jul 5, 2009, 8:34:00 AM7/5/09
to
ral...@xs4all.nl (Richard Bos) writes:
> "BartC" <ba...@freeuk.com> wrote:
>
>> "Nobody" <nob...@nowhere.com> wrote in message
>> > On Sat, 27 Jun 2009 11:37:20 -0700, Paul N wrote:
>> >> On 25 June, 23:32, pete <pfil...@mindspring.com> wrote:
>> >>
>> >>> (sqrt(2) == pow(2, 0.5))
>> >>
>> >> Is it just me, or do other people think it is silly that pow(2, 1/2)
>> >> doesn't calculate the square root of two?
>>
>> > Having type coercions propagate from top to bottom would be a nuisance for
>> > non-trivial expressions, and with no real benefit (do you genuinely have
>> > trouble remembering that 1/2 is zero, not 0.5?)
>>
>> He has a point: just about everywhere else on the planet (or even in the
>> universe), 1/2 is a half.
>
> Anywhere except inside computers. Most C code runs on computers, and
> most computers truncate integer divisions. It should be surprising to a
> greengrocer that 1/2 evaluates to 0, but not to a programmer.

Ask for half an egg, and you'll get none. 1/2 = 0 in some contexts
to a greengrocer too.

Lie Ryan

unread,
Jul 5, 2009, 12:55:10 PM7/5/09
to
Phil Carmody wrote:
> ral...@xs4all.nl (Richard Bos) writes:
>> "BartC" <ba...@freeuk.com> wrote:
>>
>>> "Nobody" <nob...@nowhere.com> wrote in message
>>>> On Sat, 27 Jun 2009 11:37:20 -0700, Paul N wrote:
>>>>> On 25 June, 23:32, pete <pfil...@mindspring.com> wrote:
>>>>>
>>>>>> (sqrt(2) == pow(2, 0.5))
>>>>> Is it just me, or do other people think it is silly that pow(2, 1/2)
>>>>> doesn't calculate the square root of two?
>>>> Having type coercions propagate from top to bottom would be a nuisance for
>>>> non-trivial expressions, and with no real benefit (do you genuinely have
>>>> trouble remembering that 1/2 is zero, not 0.5?)
>>> He has a point: just about everywhere else on the planet (or even in the
>>> universe), 1/2 is a half.
>> Anywhere except inside computers. Most C code runs on computers, and
>> most computers truncate integer divisions. It should be surprising to a
>> greengrocer that 1/2 evaluates to 0, but not to a programmer.
>
> Ask for half an egg, and you'll get none. 1/2 = 0 in some contexts
> to a greengrocer too.

No you'll get 1... 1 confused greengrocer. YMMV.

David Thompson

unread,
Jul 12, 2009, 5:13:06 PM7/12/09
to
On Mon, 29 Jun 2009 00:26:46 -0700 (PDT), Nick Keighley
<nick_keigh...@hotmail.com> wrote:

> On 28 June, 06:27, Phil Carmody <thefatphil_demun...@yahoo.co.uk>
> wrote:
> > gordonb.34...@burditt.org (Gordon Burditt) writes:
>
> > >>Is it just me, or do other people think it is silly that pow(2, 1/2)
> > >>doesn't calculate the square root of two?
> >
> > > It seems silly to make the result and/or type of the / operator
> > > depend on what the result is used for.
> >
> > Some languages do it. In those, it's not silly at all.
>
> for instance?
>

Ada includes expected return type in resolving function and operator
overloads. As an important special case, for functions with no
parameters only return type is used.

Aside from the limited perl case already mentioned, I don't know any
other that does it for general operators. C++ does it for conversions,
idiomatically called operator(); that can be leveraged to make it
(appear to) happen for other operators or functions by having those
not actually do the operation but instead return a 'proxy' whose type
defines various conversions that actually perform the deferred
operation in appropriately different ways.

0 new messages