PDA

View Full Version : Circumference of circle to many decimal places



Art
- 2nd December 2017, 02:01
Hi Guys,
I was involved in a coding challenge to calculate 2 pi r,
the circumference of a circle, given the radius as input, without any multiplication, division, or floats,
so I pretended I was using an 8 bit pic :D It was done in C, but all variables were integers,
so hopefully this BASIC is a good representation. (only the C was tested).
Cheers :)



var word input = 300 ‘ input radius
var byte twopi[19] = { 0x00,0x00,0x00,0x06,0x02,0x08,0x03,0x01,0x08,0x05, 0x03,0x00,0x07,0x01,0x07,0x09,0x05,0x09,0x00 }
var byte otput[19] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
var word adcnt = 0 ‘ counter
var byte dgcnt = 0 ‘ digit index
var byte carry = 0 ‘ carry digit


while (adcnt < input) ‘ multiply through addition
dgcnt = 17 : carry = 0
while (dgcnt > 0) ‘ cycle the digits
otput[dgcnt] = otput[dgcnt] + twopi[dgcnt] + carry : carry = 0 ‘ add digit
if (otput[dgcnt] > 9)
otput[dgcnt] = otput[dgcnt] - 10 : carry = 1
endif ‘ carry digit
dgcnt = dgcnt - 1
wend ‘ dgcnt
if (carry != 0)
otput[dgcnt] = otput[dgcnt] + 1
endif
adcnt = adcnt + 1
wend ‘ adcnt
twopi[18] = 0 // terminate string

// answer: 1884.9555921538758 is the string in the otput array

Ioannis
- 8th December 2017, 06:59
Nice idea! Thanks for sharing it.

How can you tell where the decimal dot would be?

Ioannis

Art
- 13th December 2017, 18:00
I think I made a mistake for BASIC. I don’t think you get to populate the first two arrays that way,
but in some program they would be populated at run time with the input received, so I guess that’s ok.

The addition is done the same way you were taught to do it on paper in primary school :D
You could insert a decimal point with a value such as $2E in the input arrays somewhere, which would also require you keep them aligned.
For the constant Pi2, it just goes between the first 6 and the 2. Then if the input had a decimal point, the array would have to be rotated so that
for this example, the decimal point value is also at index 4 int he array. Ignore it in calculation, but remember it’s index to be passed through to the output.
Still just as you were taught in school on paper. The decimal point is there on paper, but you do nothing with it other than also print it for the output.
In any case of course, PBP doesn’t actually know the input or the output result as any variable of it’s own, but could still display it on a screen.

Ioannis
- 13th December 2017, 21:26
The population is a C way and since you developed for C first it was expected I guess :)

Ioannis

Mike, K8LH
- 13th May 2018, 02:54
Art, if it's not too much trouble, I would love to see what the C code looked like.

Cheerful regards, Mike, K8LH

mpgmike
- 13th May 2018, 14:05
Archimedes considered his greatest achievement working out the math to calculate the volume of a circle.

Alberto
- 18th May 2018, 22:00
A circle does't have volume! Very likely you meant Area.

Alberto

mpgmike
- 19th May 2018, 01:15
Sorry, you're right, I meant volume of a sphere.

Art
- 31st May 2018, 11:43
// input ASCII into input array
// check ASCII numeric range (0x30-0x39 & 0x2E) here, and subtract 0x30 for all but 0x2E
// rotate input array left until the decimal point is aligned with twopi array

unsigned int input = 100; // 2:45am cheat
unsigned char twopi[19] = { 0x00,0x00,0x00,0x06,0x02,0x08,0x03,0x01,0x08,0x05, 0x03,0x00,0x07,0x01,0x07,0x09,0x05,0x09,0x00 };
unsigned char otput[19] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
int adcnt = 0; // counter
unsigned char dgcnt = 0; // digit index
unsigned char carry = 0; // carry digit
while (adcnt < input) { // multiply through addition
dgcnt = 17; carry = 0;
while (dgcnt > 0) { // cycle the digits
otput[dgcnt] = otput[dgcnt] + twopi[dgcnt] + carry; carry = 0;// add digit
if (otput[dgcnt] > 9) { otput[dgcnt] = otput[dgcnt] - 10; carry = 1; } // carry digit
dgcnt--;
} // dgcnt
if (carry != 0) { otput[dgcnt] = otput[dgcnt] + 1; }
adcnt++;
} // adcnt
twopi[18] = 0x00; // terminate string
printf("%d%d%d%d.%d%d%d%d%d%d",otput[0],otput[1],otput[2],otput[3],otput[4],otput[5],otput[6],otput[7],otput[8],otput[9]);

// answer: 1884.9555921538758

Art
- 31st May 2018, 11:46
But in C, since you usually have math.h with floating point, you wouldn’t actually do that.
This was part of a challenge with strict constraints.

To do it in C, it’s:


float circ;
float radius;
const float pi = 3.1415; // or however far you want to take it

radius = 10.0
circ = (2*pi)*radius;

tumbleweed
- 31st May 2018, 12:39
const float pi = 3.1415; // or however far you want to take it
With a single precision float that's about as far as you can take it... 6-7 digits.

You'll almost certainly never get the 17 digit answer.