Hacker News new | past | comments | ask | show | jobs | submit login
Donut.c Without a Math Library (a1k0n.net)
135 points by robin_reala on Jan 15, 2021 | hide | past | favorite | 22 comments



> So, how do we get sines and cosines without using sin and cos? [...] So we don’t need to track the angle at all, we only need to start at cos=1, sin=0 and rotate a circle around the origin to generate all the sines and cosines we need.

It's the main idea of the classic CORDIC algorithm (as mentioned by the author), used to be the most popular way to implement sin() and cos() on early underpowered calculators. https://en.wikipedia.org/wiki/CORDIC#Rotation_mode


Blinn's classic paper "How many ways can you draw a circle?" seems relevant (discusses CORDIC):

https://ieeexplore.ieee.org/document/4057251


I remember the first time I saw this and was just blown away by the fact that someone had the idea to do this. Some next-level creativity that lead to some next-level problem solving.

I feel trying these things opens a lot of avenues, that many people close for themselves, because they would ask: "but why on earth would I do this?".

The power of because-i-can is strong.

It's beautiful. Keep up the good w-, ehm fun. :)


I have to admit I stole the idea from this 256-byte demo (after it wiped the floor with the one I made at a demo party): http://www.pouet.net/prod.php?which=5327


Another fun circular-math-in-code is from early IOCCC. It approximates pi by calculating the area and diameter of the circle in the code. https://www.cise.ufl.edu/~manuel/obfuscate/pi.c

Explainer: https://codeexplainer.wordpress.com/2017/08/27/underscore-pi...


I love donut.c, after I’ve been teaching my students for about 6 months and they have a basic grasp of code flow, I love to show them donut.c and just watch their minds blow ^.^


In general, pretty cool stuff.

There's no need to use Sympy, it's kind of overkill. If f(x) = 1/x^2 - a, then f'(x) = -2x^-3. You can find x_new easily:

x_new = x - f(x) / f'(x)

      = x - (1/x^2 - a) / (-2x^-3)

      = x + (1/2) (x^3) (1/x^2 - a)

      = x + (1/2) (x - ax^3)

      = (3x - ax^3) / 2

      = x(3 - ax^2) / 2


Yeah, that one wasn't too hard but it's nice to have it to check your work. I didn't go into it in the post, but the real power of SymPy is its cse() function, which I used to do all the common subexpression elimination for the integer math version at the bottom.


do you have an example?


You can find a small example for generating CSE'd C code for a sympy expression at https://stackoverflow.com/questions/22665990/optimize-code-g... .

I think the built-in code generator is a bit strange, though: for example, it always prints integers as integers, and not as floats depending on the context, so code often doesn't typecheck.


I tweeted a screenshot of the Jupyter Notebook session I used to create the code at the bottom: https://twitter.com/a1k0n/status/1301261285800030208


Here's an amazing collection of JS donuts created with 140 (or less!!) characters of javascript code each. The rotaring 3D animated ones are my favorites: https://www.dwitter.net/h/donut


If you run this code on armv7, you have to change the two occurrences of char to signed char.


Oh, yeah. I had to do that for the RISC-V port, too. I'll update the post, thanks.


The monospace font used has a ligature for “fl” making the keyword “float” look weird.


It doesn't look like the <stdint.h> include is necessary.


Very nice.

Works out of the box on AmigaOS 3.1 compiled with bebbo's gcc fork.


this is art. my mind is blown away!


Should've called it donut2.c


Or twonut.c


or deuxnut.c


This is very good.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: