Browse Source

fixed an issue with composed assignment operator and added tests

master
Ludovic 'Archivist' Lagouardette 5 years ago
parent
commit
d084e918c7
2 changed files with 295 additions and 286 deletions
  1. +155
    -146
      include/9float.hpp
  2. +140
    -140
      src/tests.cpp

+ 155
- 146
include/9float.hpp View File

@ -1,147 +1,156 @@
#pragma once
#include <type_traits>
#include <iostream>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnarrowing"
namespace ninefloat{
struct private_t{};
private_t priv;
template<class integer_type, int fractionals>
class Q{
integer_type backend;
static constexpr int degen=fractionals;
constexpr Q (const integer_type value, private_t)
: backend{value}
{{std::cout<<value<< " : "<<backend<<std::endl;}}
public:
template<class srcT>
constexpr Q (const srcT value)
: backend{(integer_type)(value*(1<<degen))}
{std::cout<<value<< " : "<<backend<<std::endl;}
bool constexpr is_negative()
{
return backend&(1<<(sizeof(backend)-1));
}
integer_type constexpr data()
{
return backend;
}
bool constexpr is_positive()
{
return !is_negative();
}
Q constexpr operator+=(const Q& oth)
{
backend+=oth.backend;
return this;
}
Q constexpr operator-=(const Q& oth)
{
backend-=oth.backend;
return this;
}
Q constexpr operator/=(const Q& oth)
{
backend*=1<<Q<integer_type, fractionals>::degen;
backend/=oth.backend;
return this;
}
Q constexpr operator*=(const Q& oth)
{
if constexpr(Q<integer_type, fractionals>::degen%2==0)
{
backend=(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2));
}else{
backend=(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1));
}
return this;
}
Q constexpr operator+(const Q& oth)
{
return Q{backend+oth.backend, priv};
}
Q constexpr operator-(const Q& oth)
{
return Q{backend-oth.backend, priv};
}
Q constexpr operator/(const Q& oth)
{
return Q{(1<<Q<integer_type, fractionals>::degen)*backend/oth.backend, priv};
}
Q constexpr operator*(const Q& oth)
{
if constexpr(Q<integer_type, fractionals>::degen%2==0)
{
return Q{(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2)),priv};
}else{
return Q{(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1)),priv};
}
}
bool constexpr operator==(const Q& oth)
{
return backend == oth.backend;
}
bool constexpr operator!=(const Q& oth)
{
return backend != oth.backend;
}
bool constexpr operator>=(const Q& oth)
{
return backend >= oth.backend;
}
bool constexpr operator<=(const Q& oth)
{
return backend <= oth.backend;
}
bool constexpr operator>(const Q& oth)
{
return backend > oth.backend;
}
bool constexpr operator<(const Q& oth)
{
return backend < oth.backend;
}
constexpr operator float()
{
float n=backend;
n/=(1<<Q<integer_type, fractionals>::degen);
return n;
}
constexpr operator double()
{
double n=backend;
n/=(1<<Q<integer_type, fractionals>::degen);
return n;
}
};
#pragma GCC diagnostic pop
#pragma once
#include <type_traits>
#include <iostream>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnarrowing"
namespace ninefloat{
struct private_t{};
private_t priv;
template<class integer_type, int fractionals>
class Q{
integer_type backend;
static constexpr int degen=fractionals;
constexpr Q (const integer_type value, private_t)
: backend{value}
{}
public:
constexpr Q(const Q<integer_type,fractionals>& value)
: backend{value.backend}
{}
template<class srcT>
constexpr Q (const srcT value)
: backend{(integer_type)(value*(1<<degen))}
{}
constexpr Q ()
: backend{0}
{}
constexpr bool is_negative()
{
return backend&(1<<(sizeof(backend)-1));
}
constexpr integer_type data()
{
return backend;
}
constexpr bool is_positive()
{
return !is_negative();
}
constexpr Q<integer_type, fractionals>& operator+=(const Q& oth)
{
backend+=oth.backend;
return *this;
}
constexpr Q<integer_type, fractionals>& operator-=(const Q& oth)
{
backend-=oth.backend;
return *this;
}
constexpr Q<integer_type, fractionals>& operator/=(const Q& oth)
{
backend*=1<<Q<integer_type, fractionals>::degen;
backend/=oth.backend;
return *this;
}
constexpr Q<integer_type, fractionals>& operator*=(const Q& oth)
{
if constexpr(Q<integer_type, fractionals>::degen%2==0)
{
backend=(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2));
}else{
backend=(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1));
}
return *this;
}
constexpr Q<integer_type, fractionals> operator+(const Q& oth)
{
return Q{backend+oth.backend, priv};
}
constexpr Q<integer_type, fractionals> operator-(const Q& oth)
{
return Q{backend-oth.backend, priv};
}
constexpr Q<integer_type, fractionals> operator/(const Q& oth)
{
return Q{(1<<Q<integer_type, fractionals>::degen)*backend/oth.backend, priv};
}
constexpr Q<integer_type, fractionals> operator*(const Q& oth)
{
if constexpr(Q<integer_type, fractionals>::degen%2==0)
{
return Q{(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2)),priv};
}else{
return Q{(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1)),priv};
}
}
constexpr bool operator==(const Q& oth)
{
return backend == oth.backend;
}
constexpr bool operator!=(const Q& oth)
{
return backend != oth.backend;
}
constexpr bool operator>=(const Q& oth)
{
return backend >= oth.backend;
}
constexpr bool operator<=(const Q& oth)
{
return backend <= oth.backend;
}
constexpr bool operator>(const Q& oth)
{
return backend > oth.backend;
}
constexpr bool operator<(const Q& oth)
{
return backend < oth.backend;
}
constexpr operator float()
{
float n=backend;
n/=(1<<Q<integer_type, fractionals>::degen);
return n;
}
constexpr operator double()
{
double n=backend;
n/=(1<<Q<integer_type, fractionals>::degen);
return n;
}
};
#pragma GCC diagnostic pop
}

+ 140
- 140
src/tests.cpp View File

@ -1,141 +1,141 @@
#include "catch.hpp"
#include <iostream>
#include "9float.hpp"
using namespace ninefloat;
TEST_CASE("Addition")
{
SECTION("with positive numbers")
{
int i = 1;
float j = 0.5;
Q<int,8> target = 1.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi + qj;
REQUIRE(qres==target);
}
SECTION("with negative numbers")
{
int i = -1;
float j = -0.5;
Q<int,8> target = -1.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi + qj;
REQUIRE(qres==target);
}
SECTION("with mixed numbers")
{
int i = 1;
float j = -0.5;
Q<int,8> target = 0.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi + qj;
REQUIRE(qres==target);
}
}
TEST_CASE("Substraction")
{
SECTION("with positive numbers")
{
int i = 1;
float j = 0.5;
Q<int,8> target = 0.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi - qj;
REQUIRE(qres==target);
}
SECTION("with negative numbers")
{
int i = -1;
float j = -0.5;
Q<int,8> target = -0.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi - qj;
REQUIRE(qres==target);
}
SECTION("with mixed numbers")
{
int i = 1;
float j = -0.5;
Q<int,8> target = 1.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi - qj;
REQUIRE(qres==target);
}
}
TEST_CASE("Multiplication")
{
SECTION("with positive numbers")
{
int i = 2;
float j = 2.5;
Q<int,8> target = 5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi * qj;
REQUIRE(qres==target);
}
SECTION("with negative numbers")
{
int i = -2;
float j = -2.5;
Q<int,8> target = 5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi * qj;
REQUIRE(qres==target);
}
SECTION("with mixed numbers")
{
int i = -2;
float j = 2.5;
Q<int,8> target = -5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi * qj;
REQUIRE(qres==target);
}
}
TEST_CASE("Division")
{
SECTION("with positive numbers")
{
int i = 10;
float j = 2;
Q<int,8> target = 5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi / qj;
REQUIRE(qres==target);
}
SECTION("with negative numbers")
{
int i = -10;
float j = -5;
Q<int,8> target = 2;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi / qj;
REQUIRE(qres==target);
}
SECTION("with mixed numbers")
{
int i = -18;
float j = 3;
Q<int,8> target = -6;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi / qj;
REQUIRE(qres==target);
}
#include "catch.hpp"
#include <iostream>
#include "9float.hpp"
using namespace ninefloat;
TEST_CASE("Addition")
{
SECTION("with positive numbers")
{
int i = 1;
float j = 0.5;
Q<int,8> target = 1.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi + qj;
REQUIRE(qres==target);
}
SECTION("with negative numbers")
{
int i = -1;
float j = -0.5;
Q<int,8> target = -1.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi + qj;
REQUIRE(qres==target);
}
SECTION("with mixed numbers")
{
int i = 1;
float j = -0.5;
Q<int,8> target = 0.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi + qj;
REQUIRE(qres==target);
}
}
TEST_CASE("Substraction")
{
SECTION("with positive numbers")
{
int i = 1;
float j = 0.5;
Q<int,8> target = 0.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi - qj;
REQUIRE(qres==target);
}
SECTION("with negative numbers")
{
int i = -1;
float j = -0.5;
Q<int,8> target = -0.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi - qj;
REQUIRE(qres==target);
}
SECTION("with mixed numbers")
{
int i = 1;
float j = -0.5;
Q<int,8> target = 1.5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi - qj;
REQUIRE(qres==target);
}
}
TEST_CASE("Multiplication")
{
SECTION("with positive numbers")
{
int i = 2;
float j = 2.5;
Q<int,8> target = 5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi * qj;
REQUIRE(qres==target);
}
SECTION("with negative numbers")
{
int i = -2;
float j = -2.5;
Q<int,8> target = 5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi * qj;
REQUIRE(qres==target);
}
SECTION("with mixed numbers")
{
int i = -2;
float j = 2.5;
Q<int,8> target = -5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi * qj;
REQUIRE(qres==target);
}
}
TEST_CASE("Division")
{
SECTION("with positive numbers")
{
int i = 10;
float j = 2;
Q<int,8> target = 5;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi / qj;
REQUIRE(qres==target);
}
SECTION("with negative numbers")
{
int i = -10;
float j = -5;
Q<int,8> target = 2;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi / qj;
REQUIRE(qres==target);
}
SECTION("with mixed numbers")
{
int i = -18;
float j = 3;
Q<int,8> target = -6;
Q<int,8> qi = i;
Q<int,8> qj = j;
Q<int,8> qres = qi / qj;
REQUIRE(qres==target);
}
}

Loading…
Cancel
Save