nvdl / libfixmath Goto Github PK
View Code? Open in Web Editor NEWAutomatically exported from code.google.com/p/libfixmath
Automatically exported from code.google.com/p/libfixmath
Hi,
the recent addition of fix16_mul brakes for me on a Cortex M3 target. I'm new
to fixed point math and ARM assembler therefore I cannot be of much assistance
for debugging. Still it might brake because the asm code is not portable to the
thumb instruction set?
arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -ggdb -fomit-frame-pointer
-falign-functions=16 -std=gnu99 -ffunction-sections -fdata-sections -Wall
-Wextra -Wstrict-prototypes -Wa,-alms=libfixmath/fix16.lst -DTHUMB_PRESENT
-mno-thumb-interwork -DTHUMB_NO_INTERWORKING -MD -MP -MF .dep/fix16.o.d -mthumb
-DTHUMB -I . -Ilibfixmath/ libfixmath/fix16.c -o libfixmath/fix16.o
libfixmath/fix16.c: In function 'fix16_mul':
libfixmath/fix16.c:20: error: invalid 'asm': operand number out of range
make: *** [libfixmath/fix16.o] Error 1
At the moment I disabled the code for thumb mode via
#if (defined(__arm__) || defined(_ARM) ) && !defined(__thumb__)
Original issue reported on code.google.com by [email protected]
on 13 Mar 2011 at 10:19
What steps will reproduce the problem?
1. cd unittests && make
What is the expected output? What do you see instead?
FAILED: fix16_unittests.c:194 failures == 0
(If I add a simple
printf("Number of failures: %d\n", failures);
I get: 2961 failures)
The issue is that most of the divisions yield a wrong result.
What version of the product are you using? On what operating system?
Using the latest svn revision (r82)
Please provide any additional information below.
The complete compilation log and verbose tests run (with each failed test
result) is attached.
These gcc version and architectures FAILED the tests:
% gcc --version
gcc (GCC) 4.7.0 20120507 (Red Hat 4.7.0-5)
% uname -a
Linux xxx 3.5.2-3.fc17.x86_64 #1 SMP Tue Aug 21 19:06:52 UTC 2012 x86_64 x86_64
x86_64 GNU/Linux
% gcc --version
gcc (Debian 4.7.1-2) 4.7.1
% uname -a
Linux xxx 3.1.0-1-amd64 #1 SMP Fri Dec 23 16:37:11 UTC 2011 x86_64 GNU/Linux
But this gcc version + architecture passes the tests successfully:
% gcc --version
gcc (GCC) 4.7.1 20120721 (prerelease)
Linux xxx 3.3.1-1-ARCH #1 SMP PREEMPT Tue Apr 3 14:43:38 UTC 2012 i686 GNU/Linux
Seems like the issue is for the x86_64 architecture, then.
Original issue reported on code.google.com by [email protected]
on 31 Aug 2012 at 9:56
Attachments:
I need libfixmath but _int64 which is used very widely used in it cannot
operate on 32 bit machines. Is it possible if some one can change the codes to
32 bit compatibility.
Specifically at the moment I need sqrt, exp, atan2.
Best Regards
Original issue reported on code.google.com by [email protected]
on 10 May 2011 at 11:13
What steps will reproduce the problem?
1. cd unittests
2. make
3. fix16_str_unittests
What is the expected output? What do you see instead?
Expected no issues. Instead there's a bunch of "Value (fix16_t)X gave Y, should
be 0.00000", where all lines say "should be 0.00000".
What version of the product are you using? On what operating system?
Using MSYS under win7x64
$ gcc --version
gcc.exe (GCC) 4.7.2
$ uname -a
MINGW32_NT-6.1 user 1.0.18(0.48/3/2) 2012-11-21 22:34 i686 Msys
Please provide any additional information below.
Replacing "%0.5lf" with "%0.5f" in the following line in fix16_str_unittests.x
seems to fix the issue (line 91 currently):
snprintf(goodbuf, 13, "%0.5lf", fvalue);
According to
http://stackoverflow.com/questions/4264127/correct-format-specifier-for-double-i
n-printf specifying "l" in printf has no effect, so it should be safe to remove
it.
Original issue reported on code.google.com by [email protected]
on 19 Apr 2013 at 3:16
We need to create a proper benchmark/accuracy testing tool. Probably based of
joes tool.
Original issue reported on code.google.com by [email protected]
on 24 Feb 2011 at 2:09
What steps will reproduce the problem?
1. avr-gcc -Os -S -mmcu=atmega8 fix16.c
2. Read .s file
What is the expected output? What do you see instead?
This is a diff of sequences from fix16.c:fix16_sadd resp. fix16.c:fix16_ssub.
There is a comparison >0 that can be replaced by a comparison >= 0.
Comparisons >= 0 might be more efficient on some systems because only the sign
bit needs to be tested. AVR is an example. In this test, it does not matter
whether >=0 or >0 is used:
diff fix16-a.s fix16-b.s
23,27c23,24
< cp __zero_reg__,r12
< cpc __zero_reg__,r13
< cpc __zero_reg__,r14
< cpc __zero_reg__,r15
< brge .L13
---
> sbrc r15,7
> rjmp .L13
76,80c73,74
< cp __zero_reg__,r12
< cpc __zero_reg__,r13
< cpc __zero_reg__,r14
< cpc __zero_reg__,r15
< brge .L17
---
> sbrc r15,7
> rjmp .L17
What version of the product are you using? On what operating system?
r64, hosted on avr-unknown-none
Original issue reported on code.google.com by [email protected]
on 27 Jan 2013 at 8:14
Attachments:
Your library seems to assume that if I convert a fix16 to a float then I
originally assigned a float to it. However this is not the case. For example:
Fix16 fixedValue = 32767;
32767.0f != (float)fixedValue
(float)fixed is actually 0.499985
Here are my tests and results (ignore the ms; I had a break point set):
[----------] 9 tests from Fix16Conversion
[ RUN ] Fix16Conversion.Integer
[ OK ] Fix16Conversion.Integer (0 ms)
[ RUN ] Fix16Conversion.Float
[ OK ] Fix16Conversion.Float (0 ms)
[ RUN ] Fix16Conversion.Double
[ OK ] Fix16Conversion.Double (0 ms)
[ RUN ] Fix16Conversion.IntegerToFloat
Failure
Value of: (float)fixedValue
Actual: 0.499985
Expected: 32767.0f
Which is: 32767
[ FAILED ] Fix16Conversion.IntegerToFloat (84874 ms)
[ RUN ] Fix16Conversion.IntegerToDouble
Failure
Value of: (double)fixedValue
Actual: 0.499985
Expected: 32767.0
Which is: 32767
[ FAILED ] Fix16Conversion.IntegerToDouble (0 ms)
[ RUN ] Fix16Conversion.FloatToInteger
[ OK ] Fix16Conversion.FloatToInteger (0 ms)
[ RUN ] Fix16Conversion.FloatToDouble
[ OK ] Fix16Conversion.FloatToDouble (0 ms)
[ RUN ] Fix16Conversion.DoubleToInteger
Failure
Value of: (int)fixedValue
Actual: 2147418112
Expected: 32767
[ FAILED ] Fix16Conversion.DoubleToInteger (0 ms)
[ RUN ] Fix16Conversion.DoubleToFloat
[ OK ] Fix16Conversion.DoubleToFloat (0 ms)
[----------] 9 tests from Fix16Conversion (84875 ms total)
[==========] 10 tests from 2 test cases ran. (84875 ms total)
[ PASSED ] 7 tests.
[ FAILED ] 3 tests, listed below:
[ FAILED ] Fix16Conversion.IntegerToFloat
[ FAILED ] Fix16Conversion.IntegerToDouble
[ FAILED ] Fix16Conversion.DoubleToInteger
3 FAILED TESTS
Code for the tests:
TEST(Fix16Conversion, Integer) {
Fix16 fixedValue = 2400982;
EXPECT_EQ(2400982, (int)fixedValue);
}
TEST(Fix16Conversion, Float) {
Fix16 fixedValue = 10.0f;
EXPECT_EQ(10.0f, (float)fixedValue);
}
TEST(Fix16Conversion, Double) {
Fix16 fixedValue = 32767.0;
EXPECT_EQ(32767.0, (double)fixedValue);
}
TEST(Fix16Conversion, IntegerToFloat) {
Fix16 fixedValue = 32767;
EXPECT_EQ(32767.0f, (float)fixedValue);
}
TEST(Fix16Conversion, IntegerToDouble) {
Fix16 fixedValue = 32767;
EXPECT_EQ(32767.0, (double)fixedValue);
}
TEST(Fix16Conversion, FloatToInteger) {
Fix16 fixedValue = 10.0f;
EXPECT_EQ(10.0f, (float)fixedValue);
}
TEST(Fix16Conversion, FloatToDouble) {
Fix16 fixedValue = 10.0f;
EXPECT_EQ(10.0, (double)fixedValue);
}
TEST(Fix16Conversion, DoubleToInteger) {
Fix16 fixedValue = 32767.0;
EXPECT_EQ(32767, (int)fixedValue);
}
TEST(Fix16Conversion, DoubleToFloat) {
Fix16 fixedValue = 32767.0;
EXPECT_EQ(32767.0f, (float)fixedValue);
}
Suspected bugged code:
static inline fix16_t fix16_from_int(int a) { return a * fix16_one; }
static inline float fix16_to_float(fix16_t a) { return (float)a / fix16_one; }
static inline double fix16_to_dbl(fix16_t a) { return (double)a / fix16_one; }
What version of the product are you using? On what operating system?
Latest, mac book pro june 2007, Mountain Lion
Original issue reported on code.google.com by [email protected]
on 8 Jan 2013 at 3:14
What steps will reproduce the problem?
1. fix16_lerp16(fix16_from_int(0), fix16_from_int(10),32768)
What is the expected output? What do you see instead?
expected fix16 version of 5 (327680), actual is 0.
What version of the product are you using? On what operating system?
revision 91, MacOS Mavericks Xcode 5.1.1
Please provide any additional information below.
The MACRO
static inline int64_t int64_mul_i32_i32(int32_t x, int32_t y) { return (x * y);
}
needs to coerce the int32_t values to int64_t.
Also, the unit tests do not cover lerp functions at all.
Original issue reported on code.google.com by [email protected]
on 11 Aug 2014 at 8:35
Since fix16_t is just an integer,
Fix16 a(1);
calls Fix16(const fix16_t inValue) and sets value instead of 1 instead of
1*fix16_one.
Fix16(const fix16_t inValue) should be erased.
Original issue reported on code.google.com by [email protected]
on 30 Jul 2014 at 2:20
To reproduce issue:
#include <iostream>
#include "fixmath.h"
std::cout <<
fix16_to_float(
fix16_div(
fix16_from_float(10.0f),
fix16_from_float(1.1f)
)
);
std::cout << std::endl;
Expected versus actual output:
expected: 9.09087
actual: 0
Version/operating system/compiler details:
libfixmath version: r64
operating system: Linux Raspberry 3.5.0-22-generic #34-Ubuntu SMP Tue Jan 8 21:47:00 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
compiler: gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)
compilation flags include: -O0 -g -std=c++0x
Details:
Bug seems to be due to __builtin_clzl, which returns 44 for fix16_from_int(10), causing all sorts of problems. I guess you may be falsely assuming this function counts the number of leading zeros of a 32-bit integer, whereas really an int may have more than 32 bits.
Original issue reported on code.google.com by [email protected]
on 6 Nov 2013 at 7:51
Idea by Joe Schaack quoted from his post to the mailing list:
I was wondering if implementing a const_fix16_from_float() define would be
worth it, so that we could keep the code easy to read.
const_fix16_from_dbl(24.3323) is much easier to understand versus the decimal number 1594641.
Something like.
#define const_fix16_from_dbl(x) ((fix16_t)(x*65536.0))
This should get solved at compile time.
Original issue reported on code.google.com by [email protected]
on 24 Feb 2011 at 1:59
1. Convert a = 9.9 , b = 9.9 into fixed point
2. Call 8-bit, 32-bit, 64-bit multiplication functions
3. Covert the results back to floating point and print them
expected:98.009872 or something close to 98.009995
actual: 113.009872
Latest version, linux 64-bit PC
Trying other values worked pretty well, but it seems that values in [9.2 - 9.9]
all give bad results. 8-bit and 64-bit multiply functions worked fine.
There may be other intervals in which the function does not work.
Original issue reported on code.google.com by [email protected]
on 13 Apr 2014 at 2:08
I've found a bug with your fast implementation of sin() (FIXMATH_FAST_SIN),
this bug doesn't happen with the more accurate version.
I made an animation of a rotating cube but noticed it would shudder, i tracked
it down to the sin function providing very poor accuracy as the return value
from it reached and passed 0.
I'm running it in Visual Studio 2009 and tracking the values in the debugger so
the values i see are the 32bit number representation of the fix16_t variable
but they go like this...
1842, 899, -74, -1055, -2037, -2990, -3979, all good so far, then suddenly it
jumps back to positive with 4782, 3790, 2803, ... it then continues down
through to -65536 (-1.0) as it should do.
Original issue reported on code.google.com by [email protected]
on 21 Apr 2013 at 12:58
Doing the following will cause unexpected results;
Fix16 test = 5.0;
int divider = 2;
test /= divider;
The expected result would be 5.0, however it will instead be -32768.0 or
similar. This is because in C++ fix16_t is treated as an int, so that the
interface assumes the value 2 to be a fixed point value and not an integer.
The following code will work:
Fix16 test = 5.0;
int16_t divider = 2;
test /= divider;
This will produce the value 2.5 as expected because the interface treats
int16_t as an integer.
The problem is that I can't see a way to have the fix16_t type interoperable
with Fix16 class without sacrificing support for readable int maths. I'm not
sure that it's sensible to leave it working this way either though.
Original issue reported on code.google.com by [email protected]
on 2 Mar 2011 at 1:17
Currently the trig functions store the keys/values separately (as pointed out
by Tev). For cache optimization reasons it makes sense to store the key and
values next to each other so that they can be fetched from the same cache line
in a single operation.
Original issue reported on code.google.com by [email protected]
on 23 Jul 2012 at 9:51
What steps will reproduce the problem?
1. keil uvision
2. #define FIXMATH_NO_64BIT
3. code does not use the available 32 x 32 HW 1cycle multiply
Cortex M0+ does not have the M3 4 multipy, however it has a 32bit HW multiply
Windows 7
In reality the FIXMATH_NO_64BIT does not compile with Keil uVusuib. It's OK
with std 64 mul (after a few changes to make the compiler happy)
I was thinking of maybe changing fix16_mul, although I'm not sure how.
But are there other places where the same thing happens?
Thanks!
Original issue reported on code.google.com by [email protected]
on 7 Sep 2013 at 11:33
Rounding seems to be broken in all implementations of fix16_(s)mul,
fix16_(s)div for negative numbers:
#include <stdio.h>
#include <fix16.h>
int main()
{
fix16_t a = fix16_from_int(-1);
fix16_t b = fix16_from_int(2);
fix16_t result = fix16_div(a, b);
printf("-1/2 = %0.6f\n", fix16_to_float(result));
}
-1/2 = -0.499985
Furthermore, the ARM and non-64bit implementations of fix16_mul do not
propagate the carry from adding the rounding constant. This could cause
significant errors when the lowest word overflows.
Original issue reported on code.google.com by Petteri.Aimonen
on 29 Nov 2011 at 8:02
What steps will reproduce the problem?
1. Use the Wiring IDE
2. Copy the libfixmath source code to a folder named libfixmath
2b. Copy the libfixmath folder to the 'libraries' folder in your Wiring
Sketches folder.
3. Add the header file: compilerSettings.h (see attachment) to the libfixmath
folder.
4. Add #include "compilerSettings.h" to the beginning of every header file in
the lib math source code
(You ask why? Because I don't know how else to set these compiler options in
Wiring. To my knowledge this should work)
6. Start a new wiring sketch and add #include <fixmath.h> at the top
7. uncomment the compiler setting //#define FIXMATH_NO_OVERFLOW in
compilerSettings.h
8. Click Verify in The Wiring IDE
What is the expected output?
Successful compilation
What do you see instead?
error: libfixmath/fix16.hpp: In member function 'const Fix16 Fix16::sadd(const
Fix16&) const':
libfixmath/fix16.hpp:57: error: 'fix16_sadd' was not declared in this scope
plus similar errors for fix16_smul and fix16_sdiv.
What version of the product are you using? On what operating system?
Wiring version 100. Libfixmath version: can not find version info. downloaded
the zip end of januari. OS: OSX
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 18 Jan 2013 at 2:13
Attachments:
We need to make a set of C++ classes to encapsulate the current functions in
C++ projects. We will call this 'libfixmath++'.
Original issue reported on code.google.com by [email protected]
on 14 Feb 2011 at 9:08
It seems that some compilers/environments do not support 64-bit integers and
those which do may support them badly (slow/bloated code). We need to implement
a cross-platform backend to do 64-bit calculations where they are required
(multiplication/division).
Original issue reported on code.google.com by [email protected]
on 24 Feb 2011 at 12:53
What steps will reproduce the problem?
1.used sdiv(0xfffe0000,0xffff0000) (ie -2/-1) = 2; but we get 0x0000ffff
2.No flags has been set
3.I am using the 32bit division
What is the expected output? What do you see instead?
Ans should be 2 = 0x0002000; I get 0x0000ffff
What version of the product are you using? On what operating system?
I am working on Arm Cortex m3 lpc1768, Compiler code sorcery
Please provide any additional information below.
I tried (-1/-2) == (0xffff0000/0xfffe0000) the code hangs here
Kindly help. I am unable to work ahead.
Original issue reported on code.google.com by [email protected]
on 3 May 2012 at 9:48
I am currently using libfixmath in android development.
with FIXMATH_NO_64BIT turned on, when calculating 1587 / 2000, it gives 0xcb2,
but the correct result should be 0xcb23.
is there a error in fix16_div function ?
Original issue reported on code.google.com by [email protected]
on 10 Jun 2011 at 11:50
What steps will reproduce the problem?
1. angle = fix16_atan2(fix16_one, fix16_sqrt(fix16_from_int(3)));
2.
3.
What is the expected output? What do you see instead?
34314, 51471
What version of the product are you using? On what operating system?
Feb'12 from downloads, Jul'12 from web SVN, Windows
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 11 Apr 2013 at 4:59
Hi,
32 bit lib seems very expensive in terms of number of cycles and accuracy.
Is there any one working on it ?
Original issue reported on code.google.com by [email protected]
on 3 Mar 2011 at 3:23
I am having problems with the atan implementation.
float x = .5;
float atanx = fix16_to_float(fix16_atan(fix16_from_dbl(x)));
printf("printf atan(x) = %.3f\n",atanx);
OUTPUT:
printf atan(x) = 0.000
It appears that since x has the decimal value of 32768 which is greater than
29736 it goes into the if statement of _fix16_atan().
assuming inValue = .5 (32768 in fixed point)
tempOut = (1 + fix16_mul(inValue, inValue)); tempOut = 1 + .5*.5 = 1.25
tempOut = (1 + fix16_sqrt(tempOut)); tempOut = 1 + sqrt(1.25) =
2.118 (138805 in fixed point)
tempOut = (inValue / tempOut); tempOut =
32768/138805 = 0
tempOut = _fix16_atan(tempOut); tempOut = _atan(0) = 0
So it appears that the division line breaks it.
Assuming I pass a number that in decimal is less than 29736
float x = .25;
float atanx = fix16_to_float(fix16_atan(fix16_from_dbl(x)));
printf("val = %ld\n",fix16_from_dbl(x));
OUTPUT:
printf atan(x) = 0.255
So even with numbers less than decimal 29736 the output is still wrong
It appears that the approximation
y = x + (x^3)/3 + (x^5)/5 + (x^7)/7 + (x^9)/9 + (x^11)/11
Is a much better approximation of tangent than the atan function from graphing
it.
Original issue reported on code.google.com by [email protected]
on 22 Feb 2011 at 5:28
Generate the Doxygen documentation from the comments and release it (maybe on
the wiki).
Document some of the functions better.
Original issue reported on code.google.com by [email protected]
on 14 Feb 2011 at 9:55
What steps will reproduce the problem?
1. avr-gcc -fsyntax-only fix16.c
What is the expected output?
No warning.
What do you see instead?
fix16.c: In function 'fix16_lerp16':
fix16.c:470:5: warning: left shift count >= width of type [enabled by default]
int64_t tempOut = int64_mul_i32_i32(inArg0, ((1 << 16) - inFract));
^
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 27 Jan 2013 at 7:50
Attachments:
atan2 needs optimizing so that it maintains accuracy over the full range of
fixed point numbers while being as fast as Joes implementation (see wiki).
It may be that once tested Joes algorithm is as accurate across the full range,
if this is the case then we can use this implementation.
Original issue reported on code.google.com by [email protected]
on 24 Feb 2011 at 1:47
# What steps will reproduce the problem?
1. Compile the sources in Microsoft Visual Studio with /TP flag (compile as C++
to enable C99-like mode)
# What is the expected output? What do you see instead?
Expect passing build, but get the following errors:
- error C4146: unary minus operator applied to unsigned type, result still
unsigned fract32.c:24
- error C4146: unary minus operator applied to unsigned type, result still
unsigned fix16_sqrt32.c:83
# What version of the product are you using? On what operating system?
Microsoft Visual Studio 2013, Windows 8 - should be unrelated
# Please provide any additional information below.
Both functions return signed values. The problem comes from the fact that the
returned values themselves are unsigned yet have the unary minus operator.
Since they are unsigned, applying minus is meaningless.
Explicitly casting the values resolves the problem, so that, for example
return -fract32_usmul(-inVal, inFract);
reads
return -(int32_t)fract32_usmul(-inVal, inFract);
A patch file is attached.
Original issue reported on code.google.com by [email protected]
on 15 Jan 2014 at 10:27
Attachments:
What steps will reproduce the problem?
1. Compile
Fix16 a(2.0);
Fix16 b(4.0);
int16_t c = a+b;
What is the expected output? What do you see instead?
We get the error:
error: passing ‘const Fix16’ as ‘this’ argument of ‘Fix16::operator int16_t()’ discards qualifiers [-fpermissive]
This code should, IMHO, successfully compile with no warning.
The problem is that the operator+() method returns a const Fix16, on which we
call operator int16_t() which is not const, and can not apply on that object.
Attached is a (very simple) fix (just setting all cast operators as const).
What version of the product are you using? On what operating system?
Latest svn revision.
Original issue reported on code.google.com by [email protected]
on 2 Jul 2012 at 4:01
Attachments:
line 132 in fix16_exp.c reads:
if(x == 0) return (result << 16);
but it probably should be
if(x == 1) return (result << 16);
If I understand correctly this is to test if x was dividable by 2. In other
words, do we need to calculate decimal part.
So if x was 2^n then x is 1 after the while loop as 2^0 is 1.
Original issue reported on code.google.com by [email protected]
on 19 Dec 2013 at 2:06
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.