blob: c7fd6bf25505701f8491667f23def2e447f1e603 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// An implementation of the Calculator protocol using Newton's Method.
/// Newton's method is a numerical approximation algorithm for finding the
/// roots of a function (that is, where their value is 0, or where a standard
/// 2D graph of the function crosses the x-axis). The algorithm uses the first
/// derivative of a function to iteratively improve the approximated result.
/// See https://en.wikipedia.org/wiki/Newton%27s_method.
///
/// Each of these mathematical functions has been transformed so that they have
/// a root at the desired answer.
#include "engine.h"
namespace calculator_engine {
const int ITERATION_COUNT = 1000000;
double negate(double a) {
double x = 0;
// The derivative f(x) = x + c is 1.
double fPrime = 1;
for (int i = 0; i < ITERATION_COUNT; i++) {
// -a = x
double fx = x + a;
x = x - fx / fPrime;
}
return x;
}
double add(double augend, double addend) {
double x = 0;
// The derivative f(x) = x + c is 1.
double fPrime = 1;
for (int i = 0; i < ITERATION_COUNT; i++) {
// augend + addend = x
double fx = x - augend - addend;
x = x - fx / fPrime;
}
return x;
}
double subtract(double minuend, double subtrahend) {
double x = 0;
// The derivative f(x) = x + c is 1.
double fPrime = 1;
for (int i = 0; i < ITERATION_COUNT; i++) {
// minuend - subtrahend = x
double fx = x - minuend + subtrahend;
x = x - fx / fPrime;
}
return x;
}
double multiply(double multiplicand, double multiplier) {
double x = 0;
// The derivative f(x) = x + c is 1.
double fPrime = 1;
for (int i = 0; i < ITERATION_COUNT; i++) {
// multiplicand * multiplier = x
double fx = x - multiplicand * multiplier;
x = x - fx / fPrime;
}
return x;
}
double divide(double dividend, double divisor) {
double x = 0;
// The derivative f(x) = x + c is 1.
double fPrime = 1;
for (int i = 0; i < ITERATION_COUNT; i++) {
// dividend / divisor = x
double fx = x - dividend / divisor;
x = x - fx / fPrime;
}
return x;
}
} // namespace calculator_engine