/* MANumber - Complex numbers Copyright (C) 1995, Adam Fedor */ #ifdef GNUSTEP #include #else #import #endif #ifndef GNUSTEP #import #else #include #ifdef HAVE_FOUNDATION_NSDECIMAL_H #include #endif #endif #include #include "MathArray/NSObjectExtra.h" #include "MAConcreteNumber.h" @implementation MANumber /* Allocate the correct class for the type. I wouldn't have to do this with GNUstep. Blaa!. */ #ifndef GNUSTEP + (NSValue *)correctValue:(const void *)value withObjCType:(const char *)type { id number = nil; switch (*type) { case _C_CHR: number = [NSNumber numberWithChar:*(char *)value]; break; case _C_UCHR: number = [NSNumber numberWithUnsignedChar:*(char *)value]; break; case _C_SHT: number = [NSNumber numberWithShort:*(short *)value]; break; case _C_USHT: number = [NSNumber numberWithUnsignedShort:*(short *)value]; break; case _C_INT: number = [NSNumber numberWithInt:*(int *)value]; break; case _C_UINT: number = [NSNumber numberWithUnsignedInt:*(int *)value]; break; case _C_LNG: number = [NSNumber numberWithLong:*(long *)value]; break; case _C_ULNG: number = [NSNumber numberWithUnsignedLong:*(long *)value]; break; case 'q': number = [NSNumber numberWithLongLong:*(long long *)value]; break; case 'Q': number = [NSNumber numberWithUnsignedLongLong:*(long long *)value]; break; case _C_FLT: number = [NSNumber numberWithFloat:*(float *)value]; break; case _C_DBL: number = [NSNumber numberWithDouble:*(double *)value]; break; default: break; } return number; } #endif /* not GNUSTEP */ + (NSValue *)value:(const void *)value withObjCType:(const char *)type { #ifndef GNUSTEP id number; number = [self correctValue:value withObjCType:type]; if (number != nil) return number; #endif if (strcmp(type, @encode(complex_float)) == 0) return [self numberWithComplexFloat:*((complex_float *)value)]; else if (strcmp(type, @encode(complex_double)) == 0) return [self numberWithComplexDouble:*((complex_double *)value)]; #ifdef HAVE_FOUNDATION_NSDECIMAL_H else if (strcmp(type, @encode(NSDecimal)) == 0) return [NSDecimalNumber decimalNumberWithDecimal: *((NSDecimal *)value)]; #endif return [super value:value withObjCType:type]; } #ifndef GNUSTEP /* OSX doesn't allow creation of a concrete class from a subclass of NSNumber */ + (NSNumber *)numberWithChar:(char)value { return [NSNumber numberWithChar: value]; } + (NSNumber *)numberWithUnsignedChar:(unsigned char)value { return [NSNumber numberWithUnsignedChar: value]; } + (NSNumber *)numberWithShort:(short)value { return [NSNumber numberWithShort: value]; } + (NSNumber *)numberWithUnsignedShort:(unsigned short)value { return [NSNumber numberWithUnsignedShort: value]; } + (NSNumber *)numberWithInt:(int)value { return [NSNumber numberWithInt: value]; } + (NSNumber *)numberWithUnsignedInt:(unsigned int)value { return [NSNumber numberWithUnsignedInt: value]; } + (NSNumber *)numberWithLong:(long)value { return [NSNumber numberWithLong: value]; } + (NSNumber *)numberWithUnsignedLong:(unsigned long)value { return [NSNumber numberWithUnsignedLong: value]; } + (NSNumber *)numberWithLongLong:(long long)value { return [NSNumber numberWithLongLong: value]; } + (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value { return [NSNumber numberWithUnsignedLongLong: value]; } + (NSNumber *)numberWithFloat:(float)value { return [NSNumber numberWithFloat: value]; } + (NSNumber *)numberWithDouble:(double)value { return [NSNumber numberWithDouble: value]; } + (NSNumber *)numberWithBool:(BOOL)value { return [NSNumber numberWithBool: value]; } #endif + (id )numberWithComplexFloat:(complex_float)value { return [[[MAComplexFloatNumber alloc] initValue:&value withObjCType:NULL] autorelease]; } + (id )numberWithComplexDouble:(complex_double)value { return [[[MAComplexDoubleNumber alloc] initValue:&value withObjCType:NULL] autorelease]; } - (complex_float)complexFloatValue { [self maSubclassResponsibility:_cmd]; return (complex_float){0,0}; } - (complex_double)complexDoubleValue { [self maSubclassResponsibility:_cmd]; return (complex_double){0,0}; } // NSCopying - (id)copyWithZone:(NSZone *)zone { if (NSShouldRetainWithZone(self, zone)) return [self retain]; else return [super copyWithZone:zone]; } // NSCoding (done by subclasses) - classForCoder { return [self class]; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; } - (id)initWithCoder:(NSCoder *)coder { return [super initWithCoder:coder]; } @end @implementation NSNumber (ComplexExtensions) /* Implement these for numbers that are NOT complex */ - (complex_float)complexFloatValue { complex_float other; other.real = [self floatValue]; return other; } - (complex_double)complexDoubleValue { complex_double other; other.real = [self doubleValue]; return other; } @end