Play with

How to compute the distance between us and a planet?

C program written between 1987 and 2011

C program computes ephemerides of Sun, Moon, planets, comets, and stars using rigorous reduction methods from the _Astronomical Almanac_ and related sources. Includes PLAN404 series (see below) for positions of the planets, and a long-term extension of modern Lunar theory for the Moon's position. Reads ASCII file catalogues of stars and orbital elements. Displays all adjustments as it finds local azimuth and elevation, rise and set times, etc. Windows or MSDOS (Microsoft and Borland), Unix, VAX make files. Archive includes MSDOS executable program.

Quite complex. Better not to rewrite it.

Try it yourself

  • Debian and derivatives



  • Windows: download the zip, extract the .exe and run it from cmd


  • OS X: in a Debian VM.
sudo apt-get install aa

Run it inside a browser!

Poll a server?

No thanks!

We convert the C program to JavaScript using emscripten (emcc)

Normal compilation flow



machine code




LLVM bytecode

machine code





LLVM bytecode



emcc source files

$ emcc -h

ERROR    root: no input files
note that input files without a known suffix are
ignored, make sure your input files end with one of:
('.c', '.C', '.i', '.cpp', '.cxx', '.cc', '.c++',
'.CPP', '.CXX', '.CC', '.C++', '.ii', '.m', '.mi',
'.mm', '.mii', '.bc', '.o', '.obj', '.dylib', '.so',
'.a', '.ll', '.h', '.hxx', '.hpp', '.hh', '.H',
'.HXX', '.HPP', '.HH')

Porting to asm.js

Basically I extracted the distance calculation algorithm

and made a standalone program of it.

It uses most of the .c files in the program.


Entry point: main in planet.c


This is the function to call from the browser

#include <stdio.h>
#include "consts.h"

int main(int argc, char* argv[]) {
  double distance;
  double julian_day;
  int planet;
  sscanf(argv[1], "%lf", &julian_day);
  sscanf(argv[2], "%d", &planet);
  distance = km_to_planet(julian_day, planet);
  printf("%f\n", distance);


CC= emcc

NODE_CFLAGS=  -O2 --closure 1 --emit-symbol-map

BROWSER_CFLAGS = -O2 --closure 1 --emit-symbol-map -s MODULARIZE=1 \
   -s EXPORTED_FUNCTIONS="['_km_to_planet']"
PLANET_OBJS = planet.o planet_distance.o distance.o consts.o \
INCS = kep.h plantbl.h

all: aa conjunct moonrise planet

planet: $(PLANET_OBJS) $(INCS)
        $(CC) $(NODE_CFLAGS) -o planet-node.js $(PLANET_OBJS) -lm
        $(CC) $(BROWSER_CFLAGS) -o planet.js $(PLANET_OBJS) -lm

%.o: %c
        $(CC) $(INCS) $<


The files are big but they contain all the libc functions needed by the algorithm, rewritten in asm.js


--closure 1 removed all the unused C functions


$ make -j

$ ll *js
-rw-rw-r-- 1 montra montra 234494 Jul  3 22:13 aa.js
-rw-rw-r-- 1 montra montra 210749 Jul  3 22:13 conjunct.js
-rw-rw-r-- 1 montra montra    811 Jun 24 16:41 julian_day.js
-rw-rw-r-- 1 montra montra 208694 Jul  3 22:13 moonrise.js
-rw-rw-r-- 1 montra montra 129124 Jul  3 22:13 planet.js
-rw-rw-r-- 1 montra montra 187395 Jul  3 22:13 planet-node.js

Node.js & the browser

Command line. Inputs: julian date and the number of the planet 

Browser module with Module declaration because of -s MODULARIZE=1

$ node planet-node.js $(node julian_day.js) 4 # Mars
$ less planet-node.js  # minified because of -O2
var f;f||(f=eval("(function() { try { return Module ||
 {} } catch(e) { return {} } })()"));var ...
$ less planet.js
var Module = function(Module) {
  Module = Module || {};

var e;e||(e=eval("(function() { try { return Module || {} } ...


Lists of the functions used by the modules

$ ll *symbols
-rw-rw-r-- 1 montra montra 2855 Jul  3 22:13 aa.js.symbols
-rw-rw-r-- 1 montra montra 2602 Jul  3 22:13 conjunct.js.symbols
-rw-rw-r-- 1 montra montra 2470 Jul  3 22:13 moonrise.js.symbols
-rw-rw-r-- 1 montra montra 1694 Jul  3 22:13 planet.js.symbols
-rw-rw-r-- 1 montra montra 2266 Jul  3 22:13 planet-node.js.symbols

$ less planet.js.symbols


The heap of the modules. It's either an array in the .js file or the .mem binary file. Tradeoffs:

  • .mem: faster script startup but a separate HTTP call.
  • .js: slower startup, same HTTP call.


Generated with -O2 and ontrolled by --memory-init-file

$ ll *mem
-rw-rw-r-- 1 montra montra 167792 Jul  3 22:13 aa.js.mem
-rw-rw-r-- 1 montra montra  50576 Jul  3 22:13 conjunct.js.mem
-rw-rw-r-- 1 montra montra  51088 Jul  3 22:13 moonrise.js.mem
-rw-rw-r-- 1 montra montra 152776 Jul  3 22:13 planet.js.mem
-rw-rw-r-- 1 montra montra 153344 Jul  3 22:13 planet-node.js.mem

Copy to the web app

$ cp planet.js planet.js.mem planet.js.symbols ../newton
$ cd !$
$ less index.html
<script src="planet.js"></script>
<script src="newton-client.bundle.js"></script>
$ less newton-client.js
// this makes the asm.js module available to JavaScript
var kmToPlanet = Module().cwrap("km_to_planet", "number", 
                                ["number", "number"]);
// computes the Julian date, with decimals
var now = new Date().getTime() / 86400000 + 2440587.5;

var distanceKm = Big(kmToPlanet(now,;
// Big:
// arbitrary-precision decimal arithmetic



web app

asm.js module

PS: If you like to know more about the planets of the
Solar System you'll love

$ beefy newton-client.js:newton-client.bundle.js \

Newton and asm.js

By Paolo Montrasio

Newton and asm.js

How to power a JavaScript front end application with an old C program compiled to asm.js. Walkthrough and links to the source repositories.

  • 740
Loading comments...