Skip to content

Commit c6a3a18

Browse files
savuorvpisarev
authored andcommitted
SoftFloat integrated (opencv#8668)
* everything is put into softfloat.cpp and softfloat.hpp * WIP: try to integrate softfloat into OpenCV * extra functions removed * softfloat made stateless * CV_EXPORTS added * operators fixed * exp added, log: WIP * log32 fixed * shorter names; a lot of TODOs * log64 rewritten * cbrt32 added * minors, refactoring * "inline" -> "CV_INLINE" * cast to bool warnings fixed * several warnings fixed * fixed warning about unsigned unary minus * fixed warnings on type cast * inline -> CV_INLINE * special cases processing added (NaNs, Infs, etc.) * constants for NaN and Inf added * more macros and helper functions added * added (or fixed) tests for pow32, pow64, cbrt32 * exp-like functions fixed * minor changes * fixed random number generation for tests * tests for exp32 and exp64: values are compared to SoftFloat-based naive implementation * minor warning fix * pow(f, i) 32/64: special cases handling added * unused functions removed * refactoring is in progress (not compiling) * CV_inline added * unions {uint_t, float_t} removed * tests compilation fixed * static const members -> static methods returning const * reinterpret_cast * warning fixed * const-ness fixed * all FP calculations (even compile-time) are done in SoftFloat + minor fixes * pow(f, i) removed from interface (can cause incorrect cast) to internals of pow(f, f), tests fixed * CV_INLINE -> inline * internal constants moved to .cpp file * toInt_minMag() methods merged into toInt() methods * macros moved to .cpp file * refactoring: types renamed to softfloat and softdouble; explicit constructors, etc. * toFloat(), toDouble() -> operator float(), operator double() * removed f32/f64 prefixes from functions names * toType() methods removed, round() and trunc() functions added * minor change * minors * MSVC: warnings fixed * added int cvRound(), cvFloor, cvCeil, cvTrunc, saturate_cast<T>() * typo fixed * type cast fixed
1 parent d54b1ad commit c6a3a18

File tree

6 files changed

+5591
-0
lines changed

6 files changed

+5591
-0
lines changed

modules/core/include/opencv2/core.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#include "opencv2/core/types.hpp"
5959
#include "opencv2/core/mat.hpp"
6060
#include "opencv2/core/persistence.hpp"
61+
#include "opencv2/core/softfloat.hpp"
6162

6263
/**
6364
@defgroup core Core functionality
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
/*M///////////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4+
//
5+
// By downloading, copying, installing or using the software you agree to this license.
6+
// If you do not agree to this license, do not download, install,
7+
// copy or use the software.
8+
//
9+
//
10+
// License Agreement
11+
// For Open Source Computer Vision Library
12+
//
13+
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14+
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15+
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
16+
// Copyright (C) 2015, Itseez Inc., all rights reserved.
17+
// Third party copyrights are property of their respective owners.
18+
//
19+
// Redistribution and use in source and binary forms, with or without modification,
20+
// are permitted provided that the following conditions are met:
21+
//
22+
// * Redistribution's of source code must retain the above copyright notice,
23+
// this list of conditions and the following disclaimer.
24+
//
25+
// * Redistribution's in binary form must reproduce the above copyright notice,
26+
// this list of conditions and the following disclaimer in the documentation
27+
// and/or other materials provided with the distribution.
28+
//
29+
// * The name of the copyright holders may not be used to endorse or promote products
30+
// derived from this software without specific prior written permission.
31+
//
32+
// This software is provided by the copyright holders and contributors "as is" and
33+
// any express or implied warranties, including, but not limited to, the implied
34+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
35+
// In no event shall the Intel Corporation or contributors be liable for any direct,
36+
// indirect, incidental, special, exemplary, or consequential damages
37+
// (including, but not limited to, procurement of substitute goods or services;
38+
// loss of use, data, or profits; or business interruption) however caused
39+
// and on any theory of liability, whether in contract, strict liability,
40+
// or tort (including negligence or otherwise) arising in any way out of
41+
// the use of this software, even if advised of the possibility of such damage.
42+
//
43+
//M*/
44+
45+
/*============================================================================
46+
47+
This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
48+
Package, Release 3c, by John R. Hauser.
49+
50+
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
51+
University of California. All rights reserved.
52+
53+
Redistribution and use in source and binary forms, with or without
54+
modification, are permitted provided that the following conditions are met:
55+
56+
1. Redistributions of source code must retain the above copyright notice,
57+
this list of conditions, and the following disclaimer.
58+
59+
2. Redistributions in binary form must reproduce the above copyright notice,
60+
this list of conditions, and the following disclaimer in the documentation
61+
and/or other materials provided with the distribution.
62+
63+
3. Neither the name of the University nor the names of its contributors may
64+
be used to endorse or promote products derived from this software without
65+
specific prior written permission.
66+
67+
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
68+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
70+
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
71+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77+
78+
=============================================================================*/
79+
80+
#pragma once
81+
#ifndef softfloat_h
82+
#define softfloat_h 1
83+
84+
#include "cvdef.h"
85+
86+
namespace cv
87+
{
88+
89+
struct softfloat;
90+
struct softdouble;
91+
92+
struct CV_EXPORTS softfloat
93+
{
94+
public:
95+
softfloat() { v = 0; }
96+
softfloat( const softfloat& c) { v = c.v; }
97+
softfloat& operator=( const softfloat& c )
98+
{
99+
if(&c != this) v = c.v;
100+
return *this;
101+
}
102+
static const softfloat fromRaw( const uint32_t a ) { softfloat x; x.v = a; return x; }
103+
104+
explicit softfloat( const uint32_t );
105+
explicit softfloat( const uint64_t );
106+
explicit softfloat( const int32_t );
107+
explicit softfloat( const int64_t );
108+
explicit softfloat( const float a ) { Cv32suf s; s.f = a; v = s.u; }
109+
110+
operator softdouble() const;
111+
operator float() const { Cv32suf s; s.u = v; return s.f; }
112+
113+
softfloat operator + (const softfloat&) const;
114+
softfloat operator - (const softfloat&) const;
115+
softfloat operator * (const softfloat&) const;
116+
softfloat operator / (const softfloat&) const;
117+
softfloat operator % (const softfloat&) const;
118+
softfloat operator - () const { softfloat x; x.v = v ^ (1U << 31); return x; }
119+
120+
softfloat& operator += (const softfloat& a) { *this = *this + a; return *this; }
121+
softfloat& operator -= (const softfloat& a) { *this = *this - a; return *this; }
122+
softfloat& operator *= (const softfloat& a) { *this = *this * a; return *this; }
123+
softfloat& operator /= (const softfloat& a) { *this = *this / a; return *this; }
124+
softfloat& operator %= (const softfloat& a) { *this = *this % a; return *this; }
125+
126+
bool operator == ( const softfloat& ) const;
127+
bool operator != ( const softfloat& ) const;
128+
bool operator > ( const softfloat& ) const;
129+
bool operator >= ( const softfloat& ) const;
130+
bool operator < ( const softfloat& ) const;
131+
bool operator <= ( const softfloat& ) const;
132+
133+
bool isNaN() const { return (v & 0x7fffffff) > 0x7f800000; }
134+
bool isInf() const { return (v & 0x7fffffff) == 0x7f800000; }
135+
136+
static softfloat zero() { return softfloat::fromRaw( 0 ); }
137+
static softfloat inf() { return softfloat::fromRaw( 0xFF << 23 ); }
138+
static softfloat nan() { return softfloat::fromRaw( 0x7fffffff ); }
139+
static softfloat one() { return softfloat::fromRaw( 127 << 23 ); }
140+
141+
uint32_t v;
142+
};
143+
144+
/*----------------------------------------------------------------------------
145+
*----------------------------------------------------------------------------*/
146+
147+
struct CV_EXPORTS softdouble
148+
{
149+
public:
150+
softdouble() { }
151+
softdouble( const softdouble& c) { v = c.v; }
152+
softdouble& operator=( const softdouble& c )
153+
{
154+
if(&c != this) v = c.v;
155+
return *this;
156+
}
157+
static softdouble fromRaw( const uint64_t a ) { softdouble x; x.v = a; return x; }
158+
159+
explicit softdouble( const uint32_t );
160+
explicit softdouble( const uint64_t );
161+
explicit softdouble( const int32_t );
162+
explicit softdouble( const int64_t );
163+
explicit softdouble( const double a ) { Cv64suf s; s.f = a; v = s.u; }
164+
165+
operator softfloat() const;
166+
operator double() const { Cv64suf s; s.u = v; return s.f; }
167+
168+
softdouble operator + (const softdouble&) const;
169+
softdouble operator - (const softdouble&) const;
170+
softdouble operator * (const softdouble&) const;
171+
softdouble operator / (const softdouble&) const;
172+
softdouble operator % (const softdouble&) const;
173+
softdouble operator - () const { softdouble x; x.v = v ^ (1ULL << 63); return x; }
174+
175+
softdouble& operator += (const softdouble& a) { *this = *this + a; return *this; }
176+
softdouble& operator -= (const softdouble& a) { *this = *this - a; return *this; }
177+
softdouble& operator *= (const softdouble& a) { *this = *this * a; return *this; }
178+
softdouble& operator /= (const softdouble& a) { *this = *this / a; return *this; }
179+
softdouble& operator %= (const softdouble& a) { *this = *this % a; return *this; }
180+
181+
bool operator == ( const softdouble& ) const;
182+
bool operator != ( const softdouble& ) const;
183+
bool operator > ( const softdouble& ) const;
184+
bool operator >= ( const softdouble& ) const;
185+
bool operator < ( const softdouble& ) const;
186+
bool operator <= ( const softdouble& ) const;
187+
188+
bool isNaN() const { return (v & 0x7fffffffffffffff) > 0x7ff0000000000000; }
189+
bool isInf() const { return (v & 0x7fffffffffffffff) == 0x7ff0000000000000; }
190+
191+
static softdouble zero() { return softdouble::fromRaw( 0 ); }
192+
static softdouble inf() { return softdouble::fromRaw( (uint_fast64_t)(0x7FF) << 52 ); }
193+
static softdouble nan() { return softdouble::fromRaw( CV_BIG_INT(0x7FFFFFFFFFFFFFFF) ); }
194+
static softdouble one() { return softdouble::fromRaw( (uint_fast64_t)( 1023) << 52 ); }
195+
196+
uint64_t v;
197+
};
198+
199+
/*----------------------------------------------------------------------------
200+
*----------------------------------------------------------------------------*/
201+
202+
CV_EXPORTS softfloat mulAdd( const softfloat& a, const softfloat& b, const softfloat & c);
203+
CV_EXPORTS softdouble mulAdd( const softdouble& a, const softdouble& b, const softdouble& c);
204+
205+
CV_EXPORTS softfloat sqrt( const softfloat& a );
206+
CV_EXPORTS softdouble sqrt( const softdouble& a );
207+
}
208+
209+
/*----------------------------------------------------------------------------
210+
| Ported from OpenCV and added for usability
211+
*----------------------------------------------------------------------------*/
212+
213+
CV_EXPORTS int cvTrunc(const cv::softfloat& a);
214+
CV_EXPORTS int cvTrunc(const cv::softdouble& a);
215+
216+
CV_EXPORTS int cvRound(const cv::softfloat& a);
217+
CV_EXPORTS int cvRound(const cv::softdouble& a);
218+
219+
CV_EXPORTS int cvFloor(const cv::softfloat& a);
220+
CV_EXPORTS int cvFloor(const cv::softdouble& a);
221+
222+
CV_EXPORTS int cvCeil(const cv::softfloat& a);
223+
CV_EXPORTS int cvCeil(const cv::softdouble& a);
224+
225+
namespace cv
226+
{
227+
template<typename _Tp> static inline _Tp saturate_cast(softfloat a) { return _Tp(a); }
228+
template<typename _Tp> static inline _Tp saturate_cast(softdouble a) { return _Tp(a); }
229+
230+
template<> inline uchar saturate_cast<uchar>(softfloat a) { return (uchar)std::max(std::min(cvRound(a), (int)UCHAR_MAX), 0); }
231+
template<> inline uchar saturate_cast<uchar>(softdouble a) { return (uchar)std::max(std::min(cvRound(a), (int)UCHAR_MAX), 0); }
232+
233+
template<> inline schar saturate_cast<schar>(softfloat a) { return (schar)std::min(std::max(cvRound(a), (int)SCHAR_MIN), (int)SCHAR_MAX); }
234+
template<> inline schar saturate_cast<schar>(softdouble a) { return (schar)std::min(std::max(cvRound(a), (int)SCHAR_MIN), (int)SCHAR_MAX); }
235+
236+
template<> inline ushort saturate_cast<ushort>(softfloat a) { return (ushort)std::max(std::min(cvRound(a), (int)USHRT_MAX), 0); }
237+
template<> inline ushort saturate_cast<ushort>(softdouble a) { return (ushort)std::max(std::min(cvRound(a), (int)USHRT_MAX), 0); }
238+
239+
template<> inline short saturate_cast<short>(softfloat a) { return (short)std::min(std::max(cvRound(a), (int)SHRT_MIN), (int)SHRT_MAX); }
240+
template<> inline short saturate_cast<short>(softdouble a) { return (short)std::min(std::max(cvRound(a), (int)SHRT_MIN), (int)SHRT_MAX); }
241+
242+
template<> inline int saturate_cast<int>(softfloat a) { return cvRound(a); }
243+
template<> inline int saturate_cast<int>(softdouble a) { return cvRound(a); }
244+
245+
// we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
246+
template<> inline unsigned saturate_cast<unsigned>(softfloat a) { return cvRound(a); }
247+
template<> inline unsigned saturate_cast<unsigned>(softdouble a) { return cvRound(a); }
248+
249+
inline softfloat min(const softfloat& a, const softfloat& b) { return (a > b) ? b : a; }
250+
inline softdouble min(const softdouble& a, const softdouble& b) { return (a > b) ? b : a; }
251+
252+
inline softfloat max(const softfloat& a, const softfloat& b) { return (a > b) ? a : b; }
253+
inline softdouble max(const softdouble& a, const softdouble& b) { return (a > b) ? a : b; }
254+
255+
inline softfloat abs( softfloat a) { softfloat x; x.v = a.v & ((1U << 31) - 1); return x; }
256+
inline softdouble abs( softdouble a) { softdouble x; x.v = a.v & ((1ULL << 63) - 1); return x; }
257+
258+
CV_EXPORTS softfloat exp( const softfloat& a);
259+
CV_EXPORTS softdouble exp( const softdouble& a);
260+
261+
CV_EXPORTS softfloat log( const softfloat& a );
262+
CV_EXPORTS softdouble log( const softdouble& a );
263+
264+
CV_EXPORTS softfloat pow( const softfloat& a, const softfloat& b);
265+
CV_EXPORTS softdouble pow( const softdouble& a, const softdouble& b);
266+
267+
CV_EXPORTS softfloat cbrt(const softfloat& a);
268+
269+
}
270+
271+
#endif

modules/core/src/precomp.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
#include "opencv2/core/ocl.hpp"
5959
#endif
6060

61+
#include "opencv2/core/softfloat.hpp"
62+
6163
#include <assert.h>
6264
#include <ctype.h>
6365
#include <float.h>

0 commit comments

Comments
 (0)