How to resolve the algorithm Safe addition step by step in the Wren programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Safe addition step by step in the Wren programming language

Table of Contents

Problem Statement

Implementation of   interval arithmetic   and more generally fuzzy number arithmetic require operations that yield safe upper and lower bounds of the exact result. For example, for an addition, it is the operations   +↑   and   +↓   defined as:   a +↓ b ≤ a + b ≤ a +↑ b. Additionally it is desired that the width of the interval   (a +↑ b) - (a +↓ b)   would be about the machine epsilon after removing the exponent part. Differently to the standard floating-point arithmetic, safe interval arithmetic is accurate (but still imprecise). I.E.:   the result of each defined operation contains (though does not identify) the exact mathematical outcome. Usually a   FPU's   have machine   +,-,*,/   operations accurate within the machine precision. To illustrate it, let us consider a machine with decimal floating-point arithmetic that has the precision is 3 decimal points. If the result of the machine addition is   1.23,   then the exact mathematical result is within the interval   ]1.22, 1.24[. When the machine rounds towards zero, then the exact result is within   [1.23,1.24[.   This is the basis for an implementation of safe addition.

Show how   +↓   and   +↑   can be implemented in your language using the standard floating-point type. Define an interval type based on the standard floating-point one,   and implement an interval-valued addition of two floating-point numbers considering them exact, in short an operation that yields the interval   [a +↓ b, a +↑ b].

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Safe addition step by step in the Wren programming language

Source code in the wren programming language

/* safe_addition.wren */
class Interval {
    construct new(lower, upper) {
        if (lower.type != Num || upper.type != Num) {
            Fiber.abort("Arguments must be numbers.")
        }
        _lower = lower
        _upper = upper
    }

    lower { _lower }
    upper { _upper }

    static stepAway(x) { new(nextAfter_(x, -1/0), nextAfter_(x, 1/0)) }

    static safeAdd(x, y) { stepAway(x + y) }

    foreign static nextAfter_(x, y) // the code for this is written in C

    toString { "[%(_lower), %(_upper)]" }
}

var a = 1.2
var b = 0.03
System.print("(%(a) + %(b)) is in the range %(Interval.safeAdd(a,b))")

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "wren.h"

void Interval_nextAfter(WrenVM* vm) {
    double x = wrenGetSlotDouble(vm, 1);
    double y = wrenGetSlotDouble(vm, 2);    
    wrenSetSlotDouble(vm, 0, nextafter(x, y));
}

WrenForeignMethodFn bindForeignMethod(
    WrenVM* vm,
    const char* module,
    const char* className,
    bool isStatic,
    const char* signature) {
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "Interval") == 0) {
            if (isStatic && strcmp(signature, "nextAfter_(_,_)") == 0) {
                return Interval_nextAfter;
            }
        }
    }
    return NULL;
}

static void writeFn(WrenVM* vm, const char* text) {
    printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
    switch (errorType) {
        case WREN_ERROR_COMPILE:
            printf("[%s line %d] [Error] %s\n", module, line, msg);
            break;
        case WREN_ERROR_STACK_TRACE:
            printf("[%s line %d] in %s\n", module, line, msg);
            break;
        case WREN_ERROR_RUNTIME:
            printf("[Runtime Error] %s\n", msg);
            break;
    }
}

char *readFile(const char *fileName) {
    FILE *f = fopen(fileName, "r");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    rewind(f);
    char *script = malloc(fsize + 1);
    fread(script, 1, fsize, f);
    fclose(f);
    script[fsize] = 0;
    return script;
}

int main() {
    WrenConfiguration config;
    wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
    config.errorFn = &errorFn;
    config.bindForeignMethodFn = &bindForeignMethod;
    WrenVM* vm = wrenNewVM(&config);
    const char* module = "main";
    const char* fileName = "safe_addition.wren";
    char *script = readFile(fileName);
    WrenInterpretResult result = wrenInterpret(vm, module, script);
    switch (result) {
        case WREN_RESULT_COMPILE_ERROR:
            printf("Compile Error!\n");
            break;
        case WREN_RESULT_RUNTIME_ERROR:
            printf("Runtime Error!\n");
            break;
        case WREN_RESULT_SUCCESS:
            break;
    }
    wrenFreeVM(vm);
    free(script);
    return 0;
}


  

You may also check:How to resolve the algorithm Find the intersection of a line with a plane step by step in the AutoHotkey programming language
You may also check:How to resolve the algorithm Count the coins step by step in the Common Lisp programming language
You may also check:How to resolve the algorithm Sorting algorithms/Sleep sort step by step in the Phix programming language
You may also check:How to resolve the algorithm Loops/Do-while step by step in the OCaml programming language
You may also check:How to resolve the algorithm Compare length of two strings step by step in the Haskell programming language