diff --git a/C/pi.c b/C/pi.c
new file mode 100644
index 0000000000000000000000000000000000000000..c1494f5567eecd161e7da4d00b066c2243e2cec5
--- /dev/null
+++ b/C/pi.c
@@ -0,0 +1,32 @@
+/*
+* pi.c
+* Neil Gershenfeld 2/6/11
+* calculation of pi by a scalar sum
+* pi = 3.14159265358979323846
+*/
+
+#include <stdio.h>
+#include <sys/time.h>
+
+#define NPTS 1000000000
+
+void main() {
+   int i;
+   double a,b,c,pi,mflops;
+   unsigned long int start_time,end_time;
+   struct timeval start,end;
+   a = 0.5;
+   b = 0.75;
+   c = 0.25;
+   pi = 0;
+   pi = 0;
+   gettimeofday(&start, NULL);
+   for (i = 1; i <= NPTS; ++i)
+      pi += a/((i-b)*(i-c));
+   gettimeofday(&end, NULL);
+   start_time = start.tv_sec * 1e6 + start.tv_usec;
+   end_time = end.tv_sec * 1e6 + end.tv_usec;
+   mflops = NPTS*5.0/(end_time-start_time);
+   printf("NPTS = %d, pi = %f\n",NPTS,pi);
+   printf("time = %f, estimated MFlops = %f\n",(end_time-start_time)/1.0e6,mflops);
+   }
diff --git a/JavaScript/pi.html b/JavaScript/pi.html
new file mode 100644
index 0000000000000000000000000000000000000000..5e0d103aae51156b54d208f10a1a44e0350eaa67
--- /dev/null
+++ b/JavaScript/pi.html
@@ -0,0 +1,112 @@
+<html>
+<head>
+<script>
+
+//
+// pi.html
+// Neil Gershenfeld 1/24/17
+// pi calculation benchmark
+// pi = 3.14159265358979323846
+//
+
+function serial_benchmark() {
+   var points = parseInt(document.getElementById('serial_points').value)
+   var a = 0.5
+   var b = 0.75
+   var c = 0.25
+   var pi = 0
+   var tstart = Date.now()/1000
+   for (var i = 1; i <= points; ++i)
+      pi += a/((i-b)*(i-c));
+   var tend = Date.now()/1000
+   var mflops = points*5.0*1e-6/(tend-tstart);
+   document.getElementById('div_pi_serial').innerHTML = 'pi: '+pi
+   document.getElementById('div_time_serial').innerHTML = 'time: '+(tend-tstart).toFixed(1)+'s'
+   document.getElementById('div_flop_serial').innerHTML = 'estimated MFlops: '+mflops.toFixed(1)
+   }
+
+function reduce_benchmark() {
+   var points = parseInt(document.getElementById('reduce_points').value)
+   var a = 0.5
+   var b = 0.75
+   var c = 0.25
+   var tstart = Date.now()/1000
+   var array = new Float64Array(points)
+   var pi = array.reduce(function(sum,val,i,arr){return sum+a/(((i+1)-b)*((i+1)-c))},0)
+   var tend = Date.now()/1000
+   var mflops = points*5.0*1e-6/(tend-tstart);
+   document.getElementById('div_pi_reduce').innerHTML = 'pi: '+pi
+   document.getElementById('div_time_reduce').innerHTML = 'time: '+(tend-tstart).toFixed(1)+'s'
+   document.getElementById('div_flop_reduce').innerHTML = 'estimated MFlops: '+mflops.toFixed(1)
+   }
+
+function parallel_benchmark() {
+   document.getElementById('div_flop_parallel').innerHTML = 'estimated MFlops: calculating ...'
+   var threads = parseInt(document.getElementById('parallel_threads').value)
+   var points = parseInt(document.getElementById('parallel_points').value)
+   var results = []
+   var workers = new Array(threads)
+   var blob = new Blob(['('+parallel_worker.toString()+'())'])
+   var url = window.URL.createObjectURL(blob)
+   var tstart = Date.now()/1000
+   for (var t = 0; t < threads; ++t) {
+      workers[t] = new Worker(url)
+      workers[t].addEventListener('message',function(evt) {
+         results.push(evt.data.sum)
+         workers[evt.data.index].terminate()
+         if (results.length == threads) {
+            var tend = Date.now()/1000
+            var mflops = (threads*points)*5.0*1e-6/(tend-tstart);
+            var pi = results.reduce(function(x,y){return x+y},0)
+            document.getElementById('div_pi_parallel').innerHTML = 'pi: '+pi
+            document.getElementById('div_time_parallel').innerHTML = 'time: '+(tend-tstart).toFixed(1)+'s'
+            document.getElementById('div_flop_parallel').innerHTML = 'estimated MFlops: '+mflops.toFixed(1)
+            }
+         })
+      workers[t].postMessage({points:points,index:t})
+      }
+   window.URL.revokeObjectURL(url)
+   }
+
+function parallel_worker() {
+   self.addEventListener('message',function(evt) {
+      var points = evt.data.points
+      var index = evt.data.index
+      var a = 0.5
+      var b = 0.75
+      var c = 0.25
+      var sum = 0
+      var istart = 1+points*index
+      var iend = points*(index+1)
+      for (var i = istart; i <= iend; ++i)
+         sum += a/((i-b)*(i-c))
+      self.postMessage({sum:sum,index:index})
+      })
+   }
+
+</script>
+</head>
+<body>
+
+<button onclick='serial_benchmark()'>calculate pi serial</button><br>
+number of points: <input type='text' id='serial_points' value='1000000000' size=10>
+<div id='div_pi_serial'>pi:</div>
+<div id='div_time_serial'>time:</div>
+<div id='div_flop_serial'>estimated MFlops:</div>
+
+<br>
+
+<button onclick='reduce_benchmark()'>calculate pi reduce</button><br>
+number of points: <input type='text' id='reduce_points' value='10000000' size=10>
+<div id='div_pi_reduce'>pi:</div>
+<div id='div_time_reduce'>time:</div>
+<div id='div_flop_reduce'>estimated MFlops:</div>
+
+<br>
+
+<button onclick='parallel_benchmark()'>calculate pi parallel</button><br>
+number of threads: <input type='text' id='parallel_threads' value='4' size=3><br>
+points per thread: <input type='text' id='parallel_points' value='1000000000' size=10>
+<div id='div_pi_parallel'>pi:</div>
+<div id='div_time_parallel'>time:</div>
+<div id='div_flop_parallel'>estimated MFlops:</div>