Amazon.com Widgets FixedPoint Class
Welcome, Guest. Please login or register.
Did you miss your activation email?
June 18, 2013, 12:36:56 AM
Home Help Search chat Login Register   
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+  Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+  Old Stuff
| |-+  Shared Code Library
| | |-+  FixedPoint Class
Pages: [1]   Go Down
Print
Author Topic: FixedPoint Class  (Read 1495 times)
jdemori
Newbie
*
Posts: 4






« on: July 04, 2011, 09:05:25 PM »

This class allows you to convert a fixed point number representation to a floating point and back. Currently it is set up to convert a fixed point using the following format but can be tweaked with a little work. In the future I would see having it set in the initialization as to the specific format to be used... Enjoy.  Cool

In this instance, a fixed-point number is packed into a 32-bit unsigned integer as follows

   s i i i i i i i   i i i i i i i i   i f f f f f f f   f f f f f f f f
where:

s : sign bit (1 == negative)

i : 16 integer bits

f : 15 fraction bits

Examples:

Value

Fixed Point encoding

1.0 = 0x00008000

-1.0 = 0x80008000

2.0 = 0x00010000

-2.5 = 0x80014000

3.14 = 0x000191eb

100.99 = 0x00327eb8


Code: (Objective-C)
//
//  JDFixedPoint.h
//  playingAround
//
//  Created by Joshua Demori on 6/16/11.
//

#import <Foundation/Foundation.h>

#define BITS_WHOLE 16
#define BITS_FRACTION 15
#define BITS_SIGN BITS_WHOLE + BITS_FRACTION

#define conv_frac(fraction) (float)((float)(fraction) / (float)(1 << BITS_FRACTION))


@interface JDFixedPoint : NSObject {

@private
    long int whole;
long int fraction;
BOOL sign;

float finalResult;
long int fixedPoint;
}

@property (nonatomic) long int whole;
@property (nonatomic) long int fraction;
@property (nonatomic) BOOL sign;
@property (nonatomic) float finalResult;
@property (nonatomic) long int fixedPoint;

+ (JDFixedPoint *) allocWithFixedPoint:(long int)fixedPointValue;
- (JDFixedPoint *) initWithFixedPoint:(long int) fixedPointValue;

+ (JDFixedPoint *) allocWithFloatingPoint:(float)floatPointValue;
- (JDFixedPoint *) initWithFloatingPoint:(float) floatPointValue;

- (void) setFixedPointValue:(long int)fixedPointValue;
- (void) setFloatingPointValue:(float)floatPointValue;

- (float) floatFromFixedPointValue;
- (NSString *) stringFromFixedPointValue;


@end





Code: (Objective-C)
//
//  JDFixedPoint.m
//  playingAround
//
//  Created by Joshua Demori on 6/16/11.
//

#import "JDFixedPoint.h"

@interface JDFixedPoint ()

- (void) convert; // private method for conversion of fixed point to float

@end



@implementation JDFixedPoint

@synthesize whole, fraction, sign, finalResult, fixedPoint;


#pragma mark -
#pragma mark INIT ALLOC CODE
#pragma mark -


+ (JDFixedPoint *) allocWithFixedPoint:(long int)fixedPointValue
{

JDFixedPoint *obj = [[self alloc] initWithFixedPoint:fixedPointValue];
return obj;

}


- (JDFixedPoint *)initWithFixedPoint:(long int)fixedPointValue
{
self = [super init];
if (self) {
[self setFixedPointValue:fixedPointValue];
}

return self;
}

#pragma mark -

+ (JDFixedPoint *) allocWithFloatingPoint:(float)floatPointValue
{
JDFixedPoint *obj = [[self alloc] initWithFloatingPoint:floatPointValue];
return obj;
}


- (JDFixedPoint *) initWithFloatingPoint:(float)floatPointValue
{
self = [super init];
if (self) {
[self setFloatingPointValue:floatPointValue];
}

return self;
}


#pragma mark -
#pragma mark INTERNAL METHODS
#pragma mark -

- (void)convert
{
self.finalResult = (sign==1) ? (-1*(whole+conv_frac(fraction))) : (whole+conv_frac(fraction));


#if DEBUG == 1
NSLog(@"=============");
NSLog(@"Found \nwhole: %ld\nfraction: %ld\nsign: %d\n\n",
 self.whole,
 self.fraction,
 sign);

NSLog(@"final!: %g\n\n\n", finalResult);

#endif

}

#pragma mark -
#pragma mark INTERFACE METHODS
#pragma mark -

- (void)setFixedPointValue:(long)fixedPointValue
{
self.whole = (0x7FFF8000 & fixedPointValue) >> BITS_FRACTION;
self.fraction = fixedPointValue & 0x7FFF;
self.sign = (0x80000000 & fixedPointValue) >> BITS_SIGN;

[self convert];
}

- (void)setFloatingPointValue:(float)floatPointValue
{
double tmpWhole;
double tmpFraction;

tmpFraction = modf(floatPointValue, &tmpWhole);
self.whole = (float)tmpWhole;
self.fraction = (1 << BITS_FRACTION) * (float)tmpFraction;
self.sign = 0; // fraction holds a negative number so we default to no sign

[self convert];

#if DEBUG == 1

NSLog(@"tmpWhole: %g tmpFraction: %g", tmpWhole, tmpFraction);
NSLog(@"whole: %ld fraction: %ld sign: %d", whole, fraction, sign);

#endif

}

- (float)floatFromFixedPointValue
{
return finalResult;
}

- (NSString *)stringFromFixedPointValue
{
return [[[NSString alloc] initWithFormat:@"%g",finalResult] autorelease];
}

@end




//======================================================//
// TESTING CODE BELOW WITH RESULTS


Code: (Objective-C)
	JDFixedPoint *fxp1 = [JDFixedPoint allocWithFixedPoint:0x00008000];
JDFixedPoint *fxp2 = [JDFixedPoint allocWithFixedPoint:0x80008000];
JDFixedPoint *fxp3 = [JDFixedPoint allocWithFixedPoint:0x00010000];
JDFixedPoint *fxp4 = [JDFixedPoint allocWithFixedPoint:0x80014000];
JDFixedPoint *fxp5 = [JDFixedPoint allocWithFixedPoint:0x000191EB];
JDFixedPoint *fxp6 = [JDFixedPoint allocWithFixedPoint:0x00327EB8];

JDFixedPoint *fp1 = [JDFixedPoint allocWithFloatingPoint:1.0];
JDFixedPoint *fp2 = [JDFixedPoint allocWithFloatingPoint:-1.0];
JDFixedPoint *fp3 = [JDFixedPoint allocWithFloatingPoint:2.0];
JDFixedPoint *fp4 = [JDFixedPoint allocWithFloatingPoint:-2.5f];
JDFixedPoint *fp5 = [JDFixedPoint allocWithFloatingPoint:3.14f];
JDFixedPoint *fp6 = [JDFixedPoint allocWithFloatingPoint:100.99];

// - display fixed point values
NSLog(@"NSString: %@", [fxp1 stringFromFixedPointValue]);
NSLog(@"float: %g", [fxp1 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fxp2 stringFromFixedPointValue]);
NSLog(@"float: %g", [fxp2 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fxp3 stringFromFixedPointValue]);
NSLog(@"float: %g", [fxp3 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fxp4 stringFromFixedPointValue]);
NSLog(@"float: %g", [fxp4 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fxp5 stringFromFixedPointValue]);
NSLog(@"float: %g", [fxp5 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fxp6 stringFromFixedPointValue]);
NSLog(@"float: %g", [fxp6 floatFromFixedPointValue]);

//-- display float set values
NSLog(@"NSString: %@", [fp1 stringFromFixedPointValue]);
NSLog(@"float: %g", [fp1 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fp2 stringFromFixedPointValue]);
NSLog(@"float: %g", [fp2 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fp3 stringFromFixedPointValue]);
NSLog(@"float: %g", [fp3 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fp4 stringFromFixedPointValue]);
NSLog(@"float: %g", [fp4 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fp5 stringFromFixedPointValue]);
NSLog(@"float: %g", [fp5 floatFromFixedPointValue]);

NSLog(@"NSString: %@", [fp6 stringFromFixedPointValue]);
NSLog(@"float: %g", [fp6 floatFromFixedPointValue]);

//-- reset value
[fp1 setFloatingPointValue:-23.1234];
NSLog(@"NSString: %@", [fp1 stringFromFixedPointValue]);
NSLog(@"float: %g", [fp1 floatFromFixedPointValue]);

[fp1 setFloatingPointValue:-123.4321];
NSLog(@"NSString: %@", [fp1 stringFromFixedPointValue]);
NSLog(@"float: %g", [fp1 floatFromFixedPointValue]);



2011-07-04 23:58:32.196 playingAround[39016:903] =============
2011-07-04 23:58:32.197 playingAround[39016:903] Found
whole: 1
fraction: 0
sign: 0

2011-07-04 23:58:32.198 playingAround[39016:903] final!: 1

2011-07-04 23:58:32.199 playingAround[39016:903] =============
2011-07-04 23:58:32.199 playingAround[39016:903] Found
whole: 1
fraction: 0
sign: 1

2011-07-04 23:58:32.200 playingAround[39016:903] final!: -1


2011-07-04 23:58:32.202 playingAround[39016:903] =============
2011-07-04 23:58:32.206 playingAround[39016:903] Found
whole: 2
fraction: 0
sign: 0

2011-07-04 23:58:32.207 playingAround[39016:903] final!: 2


2011-07-04 23:58:32.208 playingAround[39016:903] =============
2011-07-04 23:58:32.209 playingAround[39016:903] Found
whole: 2
fraction: 16384
sign: 1

2011-07-04 23:58:32.210 playingAround[39016:903] final!: -2.5


2011-07-04 23:58:32.211 playingAround[39016:903] =============
2011-07-04 23:58:32.212 playingAround[39016:903] Found
whole: 3
fraction: 4587
sign: 0

2011-07-04 23:58:32.213 playingAround[39016:903] final!: 3.13998


2011-07-04 23:58:32.214 playingAround[39016:903] =============
2011-07-04 23:58:32.215 playingAround[39016:903] Found
whole: 100
fraction: 32440
sign: 0

2011-07-04 23:58:32.217 playingAround[39016:903] final!: 100.99


2011-07-04 23:58:32.217 playingAround[39016:903] =============
2011-07-04 23:58:32.218 playingAround[39016:903] Found
whole: 1
fraction: 0
sign: 0

2011-07-04 23:58:32.218 playingAround[39016:903] final!: 1


2011-07-04 23:58:32.219 playingAround[39016:903] tmpWhole: 1 tmpFraction: 0
2011-07-04 23:58:32.219 playingAround[39016:903] whole: 1 fraction: 0 sign: 0
2011-07-04 23:58:32.224 playingAround[39016:903] =============
2011-07-04 23:58:32.225 playingAround[39016:903] Found
whole: -1
fraction: 0
sign: 0

2011-07-04 23:58:32.225 playingAround[39016:903] final!: -1


2011-07-04 23:58:32.226 playingAround[39016:903] tmpWhole: -1 tmpFraction: -0
2011-07-04 23:58:32.228 playingAround[39016:903] whole: -1 fraction: 0 sign: 0
2011-07-04 23:58:32.229 playingAround[39016:903] =============
2011-07-04 23:58:32.229 playingAround[39016:903] Found
whole: 2
fraction: 0
sign: 0

2011-07-04 23:58:32.230 playingAround[39016:903] final!: 2


2011-07-04 23:58:32.231 playingAround[39016:903] tmpWhole: 2 tmpFraction: 0
2011-07-04 23:58:32.232 playingAround[39016:903] whole: 2 fraction: 0 sign: 0
2011-07-04 23:58:32.233 playingAround[39016:903] =============
2011-07-04 23:58:32.234 playingAround[39016:903] Found
whole: -2
fraction: -16384
sign: 0

2011-07-04 23:58:32.235 playingAround[39016:903] final!: -2.5


2011-07-04 23:58:32.236 playingAround[39016:903] tmpWhole: -2 tmpFraction: -0.5
2011-07-04 23:58:32.239 playingAround[39016:903] whole: -2 fraction: -16384 sign: 0
2011-07-04 23:58:32.240 playingAround[39016:903] =============
2011-07-04 23:58:32.242 playingAround[39016:903] Found
whole: 3
fraction: 4587
sign: 0

2011-07-04 23:58:32.243 playingAround[39016:903] final!: 3.13998


2011-07-04 23:58:32.244 playingAround[39016:903] tmpWhole: 3 tmpFraction: 0.14
2011-07-04 23:58:32.260 playingAround[39016:903] whole: 3 fraction: 4587 sign: 0
2011-07-04 23:58:32.261 playingAround[39016:903] =============
2011-07-04 23:58:32.261 playingAround[39016:903] Found
whole: 100
fraction: 32440
sign: 0

2011-07-04 23:58:32.262 playingAround[39016:903] final!: 100.99


2011-07-04 23:58:32.263 playingAround[39016:903] tmpWhole: 100 tmpFraction: 0.989998
2011-07-04 23:58:32.263 playingAround[39016:903] whole: 100 fraction: 32440 sign: 0
2011-07-04 23:58:32.264 playingAround[39016:903] NSString: 1
2011-07-04 23:58:32.264 playingAround[39016:903] float: 1
2011-07-04 23:58:32.265 playingAround[39016:903] NSString: -1
2011-07-04 23:58:32.265 playingAround[39016:903] float: -1
2011-07-04 23:58:32.266 playingAround[39016:903] NSString: 2
2011-07-04 23:58:32.266 playingAround[39016:903] float: 2
2011-07-04 23:58:32.267 playingAround[39016:903] NSString: -2.5
2011-07-04 23:58:32.267 playingAround[39016:903] float: -2.5
2011-07-04 23:58:32.268 playingAround[39016:903] NSString: 3.13998
2011-07-04 23:58:32.268 playingAround[39016:903] float: 3.13998
2011-07-04 23:58:32.269 playingAround[39016:903] NSString: 100.99
2011-07-04 23:58:32.317 playingAround[39016:903] float: 100.99
2011-07-04 23:58:32.319 playingAround[39016:903] NSString: 1
2011-07-04 23:58:32.319 playingAround[39016:903] float: 1
2011-07-04 23:58:32.323 playingAround[39016:903] NSString: -1
2011-07-04 23:58:32.324 playingAround[39016:903] float: -1
2011-07-04 23:58:32.326 playingAround[39016:903] NSString: 2
2011-07-04 23:58:32.328 playingAround[39016:903] float: 2
2011-07-04 23:58:32.329 playingAround[39016:903] NSString: -2.5
2011-07-04 23:58:32.330 playingAround[39016:903] float: -2.5
2011-07-04 23:58:32.331 playingAround[39016:903] NSString: 3.13998
2011-07-04 23:58:32.332 playingAround[39016:903] float: 3.13998
2011-07-04 23:58:32.333 playingAround[39016:903] NSString: 100.99
2011-07-04 23:58:32.334 playingAround[39016:903] float: 100.99
2011-07-04 23:58:32.335 playingAround[39016:903] =============
2011-07-04 23:58:32.336 playingAround[39016:903] Found
whole: -23
fraction: -4043
sign: 0

2011-07-04 23:58:32.339 playingAround[39016:903] final!: -23.1234


2011-07-04 23:58:32.340 playingAround[39016:903] tmpWhole: -23 tmpFraction: -0.1234
2011-07-04 23:58:32.340 playingAround[39016:903] whole: -23 fraction: -4043 sign: 0
2011-07-04 23:58:32.340 playingAround[39016:903] NSString: -23.1234
2011-07-04 23:58:32.341 playingAround[39016:903] float: -23.1234
2011-07-04 23:58:32.341 playingAround[39016:903] =============
2011-07-04 23:58:32.341 playingAround[39016:903] Found
whole: -123
fraction: -14159
sign: 0

2011-07-04 23:58:32.344 playingAround[39016:903] final!: -123.432


2011-07-04 23:58:32.347 playingAround[39016:903] tmpWhole: -123 tmpFraction: -0.432098
2011-07-04 23:58:32.348 playingAround[39016:903] whole: -123 fraction: -14159 sign: 0
2011-07-04 23:58:32.350 playingAround[39016:903] NSString: -123.432
2011-07-04 23:58:32.350 playingAround[39016:903] float: -123.432
« Last Edit: July 04, 2011, 09:13:00 PM by jdemori » Logged
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #1 on: July 05, 2011, 02:42:04 PM »

Hey, thanks for posting this.  I'll have to take  a closer look when I get a chance.   Would you mind posting a few sentences to tell the readers why they might need/want to use this class?

Thanks,

Steve
Logged
jdemori
Newbie
*
Posts: 4






« Reply #2 on: July 05, 2011, 07:47:16 PM »

Ok here goes.. Some times you may have to deal with file formats that were encoded in a particular way by a certain company for certain mathematical precision or speed, but what ever the case you may need to work with it in another format. This particular class allows you to take one encoding of a fixed point representation to a floating point representation or vice versa.

Also from my basic understanding of floats and fixed point math, floating point math is not a precise representation and can be slower on some cpus without a floating point unit though that is becoming rare today... For example the value 0.10 may be represented as 0.1000000001 (approximate) which can cause problems especially with financial type math.

When I built iTip Jar for the iphone I used a special class for this very reason, NSDecimalNumber. Very important when using math type calculations.

I've heard in the early days some developers deposited those fractional amounts into their accounts. Adds up quick.. Like in Hackers the movie Tongue
Logged
Pages: [1]   Go Up
Print
Jump to:  



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.