[colobot] 02/100: Added half-precision floating-point format implementation

Didier Raboud odyx at moszumanska.debian.org
Thu Jun 1 18:10:13 UTC 2017


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian/master
in repository colobot.

commit c5b5435b4a36bdc74eb80f6c0c966753d6e73da2
Author: Tomasz Kapuściński <tomaszkax86 at gmail.com>
Date:   Fri Nov 4 11:35:55 2016 +0100

    Added half-precision floating-point format implementation
---
 src/CMakeLists.txt |   2 +
 src/math/all.h     |   1 +
 src/math/half.cpp  | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/math/half.h    | 103 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 222 insertions(+)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 957cb70..dd54926 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -243,6 +243,8 @@ set(BASE_SOURCES
     math/const.h
     math/func.h
     math/geometry.h
+    math/half.cpp
+    math/half.h
     math/intpoint.h
     math/matrix.h
     math/point.h
diff --git a/src/math/all.h b/src/math/all.h
index 7137c61..f56a56f 100644
--- a/src/math/all.h
+++ b/src/math/all.h
@@ -28,6 +28,7 @@
 #include "math/const.h"
 #include "math/func.h"
 #include "math/geometry.h"
+#include "math/half.h"
 #include "math/matrix.h"
 #include "math/point.h"
 #include "math/vector.h"
diff --git a/src/math/half.cpp b/src/math/half.cpp
new file mode 100644
index 0000000..263a8e7
--- /dev/null
+++ b/src/math/half.cpp
@@ -0,0 +1,116 @@
+/*
+* This file is part of the Colobot: Gold Edition source code
+* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
+* http://epsitec.ch; http://colobot.info; http://github.com/colobot
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see http://gnu.org/licenses
+*/
+
+#include "math/half.h"
+
+#include <cmath>
+#include <iomanip>
+#include <limits>
+
+// Math module namespace
+namespace Math
+{
+
+//! Converts float to half-float
+uint16_t FloatToHalf(float value)
+{
+    uint16_t sign = (copysign(1.0f, value) > 0.0f ? 0x0000 : 0x8000);
+
+    // Infinity
+    if (isinf(value))
+    {
+        return sign | 0x7C00;
+    }
+    // NaN
+    else if (isnan(value))
+    {
+        return sign | 0x7FFF;
+    }
+
+    int exponent;
+
+    float significand = fabs(frexp(value, &exponent));
+
+    // Exponent bias
+    exponent += 15;
+
+    // Crosses upper boundary, clamp to infinity
+    if (exponent > 31)
+    {
+        return sign | 0x7C00;
+    }
+    // Crosses lower boundary, clamp to zero
+    else if (exponent <= 0)
+    {
+        return sign | 0x0000;
+    }
+    // Zero
+    else if (significand < 0.25f)
+    {
+        return sign | 0x0000;
+    }
+
+    // Normal value
+    uint16_t mantissa = static_cast<uint16_t>(ldexp(2 * significand - 1, 10));
+
+    uint16_t bits = sign | mantissa | ((exponent - 1) << 10);
+
+    return bits;
+}
+
+//! Converts half-float to float
+float HaltToFloat(uint16_t value)
+{
+    int exponent = (value >> 10) & 0x001F;
+    int mantissa = (value >> 0) & 0x03FF;
+
+    float result;
+
+    // Zero
+    if ((exponent == 0) && (mantissa == 0))
+    {
+        result = 0.0f;
+    }
+    // Subnormal
+    else if ((exponent == 0) && (mantissa != 0))
+    {
+        result = ldexp(static_cast<float>(mantissa), -24);
+    }
+    // Infinity
+    else if ((exponent == 31) && (mantissa == 0))
+    {
+        result = std::numeric_limits<float>::infinity();
+    }
+    // NaN
+    else if ((exponent == 31) && (mantissa != 0))
+    {
+        result = nanf("");
+    }
+    // Normal number
+    else
+    {
+        result = ldexp(static_cast<float>(mantissa | 0x0400), exponent - 25);
+    }
+
+    float sign = ((value & 0x8000) == 0 ? 1.0f : -1.0f);
+
+    return copysignf(result, sign);
+}
+
+} // namespace Math
diff --git a/src/math/half.h b/src/math/half.h
new file mode 100644
index 0000000..a5e44f4
--- /dev/null
+++ b/src/math/half.h
@@ -0,0 +1,103 @@
+/*
+* This file is part of the Colobot: Gold Edition source code
+* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
+* http://epsitec.ch; http://colobot.info; http://github.com/colobot
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see http://gnu.org/licenses
+*/
+
+/**
+* \file math/half.h
+* \brief Implementation of half-precision floating point values.
+*/
+
+#pragma once
+
+#include <cstdint>
+
+// Math module namespace
+namespace Math
+{
+
+//! Converts float to half-float binary representation
+uint16_t FloatToHalf(float value);
+
+//! Converts half-float binary representation to float
+float HaltToFloat(uint16_t value);
+
+/**
+* \struct half
+* \brief half-precision floating point type
+*
+* Represents a half-precision floating point value.
+* Contains the required methods for converting to and from ints and floats.
+*
+* This type is for storage only.
+* Conversion is expensive and should be avoided if possible.
+*/
+struct half
+{
+    //! 16-bit binary representation of half-float
+    uint16_t bits;
+
+    //! Default constructor
+    half()
+        : bits(0)
+    {
+
+    }
+
+    //! Copy constructor
+    half(const half& other)
+        : bits(other.bits)
+    {
+
+    }
+
+    //! Copy operator
+    half& operator=(const half& other)
+    {
+        bits = other.bits;
+
+        return *this;
+    }
+
+    //! Conversion constructor from int
+    explicit half(int value)
+        : bits(FloatToHalf(static_cast<float>(value)))
+    {
+
+    }
+
+    //! Conversion constructor from float
+    explicit half(float value)
+        : bits(FloatToHalf(value))
+    {
+
+    }
+
+    //! Conversion operator to int
+    explicit operator int() const
+    {
+        return static_cast<int>(HaltToFloat(bits));
+    }
+
+    //! Conversion operator to float
+    explicit operator float() const
+    {
+        return HaltToFloat(bits);
+    }
+};
+
+} // namespace Math

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list