1 
2 //metadoc Number category Core
3 //metadoc Number copyright Steve Dekorte 2002
4 //metadoc Number license BSD revised
5 /*metadoc Number description
6 A container for a double (a 64bit floating point number on most platforms).
7 */
8 
9 #ifdef _MSC_VER
10 #define _USE_MATH_DEFINES
11 #endif
12 
13 #include "IoNumber.h"
14 #include "IoObject.h"
15 #include "IoState.h"
16 #include "IoSeq.h"
17 #include "IoSeq.h"
18 #include "IoDate.h"
19 #include "IoState.h"
20 
21 #include <ctype.h>
22 #include <assert.h>
23 
24 #include <setjmp.h>
25 #if defined(_BSD_PPC_SETJMP_H_)
26 #include <machine/limits.h>
27 #else
28 #include <limits.h>
29 #endif
30 
31 #if defined(__SYMBIAN32__)
32 /* TODO: Fix symbian constants */
33 #define FLT_MAX 0.0
34 #define FLT_MIN 0.0
35 #else
36 #include <float.h>
37 #endif
38 
39 #ifndef log2
log2(double n)40 double log2(double n)
41 {
42 	return log(n) / log(2);
43 }
44 #endif
45 
46 #ifdef __FreeBSD__
47 #define log2(x) (log(x) / M_LN2)
48 #endif
49 
50 #define DATA(self) CNUMBER(self)
51 
52 static const char *protoId = "Number";
53 
IoNumber_numberForDouble_canUse_(IoNumber * self,double n,IoNumber * other)54 IoNumber *IoNumber_numberForDouble_canUse_(IoNumber *self, double n, IoNumber *other)
55 {
56 	if (DATA(self)  == n) return self;
57 	if (DATA(other) == n) return other;
58 	return IONUMBER(n);
59 }
60 
IoNumber_newTag(void * state)61 IoTag *IoNumber_newTag(void *state)
62 {
63 	IoTag *tag = IoTag_newWithName_(protoId);
64 	IoTag_state_(tag, state);
65 	IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoNumber_rawClone);
66 	IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoNumber_free);
67 	IoTag_compareFunc_(tag, (IoTagCompareFunc *)IoNumber_compare);
68 	//IoTag_writeToStreamFunc_(tag, (IoTagWriteToStreamFunc *)IoNumber_writeToStream_);
69 	//IoTag_readFromStreamFunc_(tag, (IoTagReadFromStreamFunc *)IoNumber_readFromStream_);
70 	assert(sizeof(double) <= sizeof(void *)*2);
71 	/*printf("Number tag = %p\n", (void *)tag);*/
72 	return tag;
73 }
74 
75 /*
76 void IoNumber_writeToStream_(IoNumber *self, BStream *stream)
77 {
78 	BStream_writeTaggedDouble_(stream, DATA(self));
79 }
80 
81 void *IoNumber_readFromStream_(IoNumber *self, BStream *stream)
82 {
83 	DATA(self) = BStream_readTaggedDouble(stream);
84 	return self;
85 }
86 */
87 
88 // #define IONUMBER_IS_MUTABLE
89 
IoNumber_proto(void * state)90 IoNumber *IoNumber_proto(void *state)
91 {
92 	IoMethodTable methodTable[] = {
93 	{"asNumber", IoNumber_asNumber},
94 	{"+", IoNumber_add_},
95 	{"-", IoNumber_subtract},
96 	{"*", IoNumber_multiply},
97 	{"/", IoNumber_divide},
98 	//{"print", IoNumber_printNumber},
99 
100 	{"asString", IoNumber_asString},
101 	{"asBuffer", IoNumber_asBuffer},
102 	{"asCharacter", IoNumber_asCharacter},
103 	{"asUint32Buffer", IoNumber_asUint32Buffer},
104 	//{"asDate", IoNumber_asDate},
105 
106 	{"abs", IoNumber_abs},
107 	{"acos", IoNumber_acos},
108 	{"asin", IoNumber_asin},
109 	{"atan", IoNumber_atan},
110 	{"atan2", IoNumber_atan2},
111 	{"ceil", IoNumber_ceil},
112 	{"cos", IoNumber_cos},
113 	// {"deg", IoNumber_deg}
114 	{"exp", IoNumber_exp},
115 	{"factorial", IoNumber_factorial},
116 	{"floor", IoNumber_floor},
117 	{"log", IoNumber_log},
118 	{"log2", IoNumber_log2},
119 	{"log10", IoNumber_log10},
120 	{"max", IoNumber_max},
121 	{"min", IoNumber_min},
122 	{"%", IoNumber_mod},
123 	{"mod", IoNumber_mod},
124 	{"**", IoNumber_pow},
125 	{"pow", IoNumber_pow},
126 	{"round", IoNumber_round},
127 	{"roundDown", IoNumber_roundDown},
128 	{"sin", IoNumber_sin},
129 	{"sqrt", IoNumber_sqrt},
130 	{"squared", IoNumber_squared},
131 	{"cubed", IoNumber_cubed},
132 	{"tan", IoNumber_tan},
133 	{"toggle", IoNumber_toggle},
134 
135 	// logic operations
136 
137 	{"&", IoNumber_bitwiseAnd},
138 	{"|", IoNumber_bitwiseOr},
139 	{"^", IoNumber_bitwiseXor},
140 	{"<<", IoNumber_bitShiftLeft},
141 	{">>", IoNumber_bitShiftRight},
142 
143 	{"bitwiseAnd", IoNumber_bitwiseAnd},
144 	{"bitwiseOr", IoNumber_bitwiseOr},
145 	{"bitwiseXor", IoNumber_bitwiseXor},
146 	{"bitwiseComplement", IoNumber_bitwiseComplement},
147 	{"shiftLeft", IoNumber_bitShiftLeft},
148 	{"shiftRight", IoNumber_bitShiftRight},
149 
150 	// even and odd
151 
152 	{"isEven", IoNumber_isEven},
153 	{"isOdd", IoNumber_isOdd},
154 
155 	// character operations
156 
157 	{"isAlphaNumeric", IoNumber_isAlphaNumeric},
158 	{"isLetter", IoNumber_isLetter},
159 	{"isControlCharacter", IoNumber_isControlCharacter},
160 	{"isDigit", IoNumber_isDigit},
161 	{"isGraph", IoNumber_isGraph},
162 	{"isLowercase", IoNumber_isLowercase},
163 	{"isUppercase", IoNumber_isUppercase},
164 	{"isPrint", IoNumber_isPrint},
165 	{"isPunctuation", IoNumber_isPunctuation},
166 	{"isSpace", IoNumber_isSpace},
167 	{"isHexDigit", IoNumber_isHexDigit},
168 
169 	{"asLowercase", IoNumber_asLowercase},
170 	{"asUppercase", IoNumber_asUppercase},
171 
172 	{"between", IoNumber_between},
173 	{"clip", IoNumber_clip},
174 	{"negate", IoNumber_negate},
175 	{"at", IoNumber_at},
176 
177 	{"integerMax", IoNumber_integerMax},
178 	{"integerMin", IoNumber_integerMin},
179 	{"longMax", IoNumber_longMax},
180 	{"longMin", IoNumber_longMin},
181 	{"shortMax", IoNumber_shortMax},
182 	{"shortMin", IoNumber_shortMin},
183 	{"unsignedLongMax", IoNumber_unsignedLongMax},
184 	{"unsignedIntMax", IoNumber_unsignedIntMax},
185 	{"floatMax", IoNumber_floatMax},
186 	{"floatMin", IoNumber_floatMin},
187 	{"isNan", IoNumber_isNan},
188 
189 	{"repeat", IoNumber_repeat},
190 
191 	{NULL, NULL},
192 	};
193 
194 	IoObject *self = IoObject_new(state);
195 
196 	IoObject_tag_(self, IoNumber_newTag(state));
197 	DATA(self) = 0;
198 	IoState_registerProtoWithId_((IoState *)state, self, protoId);
199 
200 	IoObject_addMethodTable_(self, methodTable);
201 	return self;
202 }
203 
IoNumber_rawClone(IoNumber * proto)204 IoNumber *IoNumber_rawClone(IoNumber *proto)
205 {
206 	IoObject *self = IoObject_rawClonePrimitive(proto);
207 	DATA(self) = DATA(proto);
208 	return self;
209 }
210 
IoNumber_newWithDouble_(void * state,double n)211 IoNumber *IoNumber_newWithDouble_(void *state, double n)
212 {
213 	// Normalize NAN, since there are positive and negative NANs
214 	if (isnan(n))
215 	{
216 		n = NAN;
217 	}
218 	IoNumber *proto = IoState_protoWithId_((IoState *)state, protoId);
219 	IoNumber *self = IOCLONE(proto); // since Numbers have no refs, we can avoid IOCLONE
220 	DATA(self) = n;
221 	return self;
222 }
223 
IoNumber_newCopyOf_(IoNumber * self)224 IoNumber *IoNumber_newCopyOf_(IoNumber *self)
225 {
226 	return IONUMBER(DATA(self));
227 }
228 
IoNumber_copyFrom_(IoNumber * self,IoNumber * number)229 void IoNumber_copyFrom_(IoNumber *self, IoNumber *number)
230 {
231 	DATA(self) = DATA(number);
232 }
233 
IoNumber_free(IoNumber * self)234 void IoNumber_free(IoNumber *self)
235 {
236 	/* need this so Object won't try to io_free IoObject_dataPointer(self) */
237 }
238 
IoNumber_asStackUArray(IoNumber * self)239 UArray IoNumber_asStackUArray(IoNumber *self)
240 {
241 	UArray a = UArray_stackAllocedEmptyUArray();
242 	a.size = 1;
243 
244 	if (sizeof(double) == 4)
245 	{
246 		a.itemType = CTYPE_float32_t;
247 		a.itemSize = 4;
248 	}
249 	else
250 	{
251 		a.itemType = CTYPE_float64_t;
252 		a.itemSize = 8;
253 	}
254 
255 	a.data = (uint8_t *)(&DATA(self));
256 	return a;
257 }
258 
IoNumber_asInt(IoNumber * self)259 int IoNumber_asInt(IoNumber *self)
260 {
261 	return (int)(DATA(self));
262 }
263 
IoNumber_asLong(IoNumber * self)264 long IoNumber_asLong(IoNumber *self)
265 {
266 	return (long)(DATA(self));
267 }
268 
IoNumber_asFloat(IoNumber * self)269 float IoNumber_asFloat(IoNumber *self)
270 {
271 	return (float)DATA(self);
272 }
273 
IoNumber_asDouble(IoNumber * self)274 double IoNumber_asDouble(IoNumber *self)
275 {
276 	return (double)DATA(self);
277 }
278 
IoNumber_compare(IoNumber * self,IoNumber * v)279 int IoNumber_compare(IoNumber *self, IoNumber *v)
280 {
281 	if (ISNUMBER(v))
282 	{
283 		if (DATA(self) == DATA(v))
284 		{
285 			return 0;
286 		}
287 		return (DATA(self) > DATA(v)) ? 1 : -1;
288 	}
289 	return IoObject_defaultCompare(self, v);
290 }
291 
IoNumber_Double_intoCString_(double n,char * s,size_t maxSize)292 void IoNumber_Double_intoCString_(double n, char *s, size_t maxSize)
293 {
294 	if (n == (int)n)
295 	{
296 		snprintf(s, maxSize, "%d", (int)n);
297 	}
298 	else if (n > INT_MAX)
299 	{
300 		snprintf(s, maxSize, "%e", n);
301 	}
302 	else
303 	{
304 		long l;
305 
306 		snprintf(s, maxSize, "%.16f", n);
307 
308 		// remove the trailing zeros ex: 10.00 -> 10
309 
310 		l = (long)strlen(s) - 1;
311 
312 		while (l > 0)
313 		{
314 			if (s[l] == '0') { s[l] = 0; l--; continue; }
315 			if (s[l] == '.') { s[l] = 0; l--; break; }
316 			break;
317 		}
318 	}
319 }
320 
IoNumber_print(IoNumber * self)321 void IoNumber_print(IoNumber *self)
322 {
323 	double d = DATA(self);
324 	char s[128];
325 
326 	IoNumber_Double_intoCString_(d, s, 127);
327 	IoState_print_(IOSTATE, "%s", s);
328 }
329 
330 // -----------------------------------------------------------
331 
332 #ifdef _WIN32
333 #include <winsock2.h>
334 #else
335 #include <arpa/inet.h>
336 #endif
337 
338 //IO_METHOD(IoNumber, htonl)
339 //{
340 //    /* doc htonl
341 //    Returns a new number with the first 4 bytes of the receiver switched from
342 //host to network byte order.
343 //    */
344 //
345 //    IoNumber *num = IONUMBER(0);
346 //    IoObject_setDataUint32_(num, htonl(IoObject_dataUint32(self)));
347 //    return num;
348 //}
349 
350 //IO_METHOD(IoNumber, ntohl)
351 //{
352 //    /* doc ntohl
353 //Returns a new number with the first 4 bytes of the receiver switched from
354 //network to host byte order.
355 //    */
356 //
357 //	IoNumber *num = IONUMBER(0);
358 //	IoObject_setDataUint32_(num, ntohl(IoObject_dataUint32(self)));
359 //	return num;
360 //}
361 
362 // -----------------------------------------------------------
363 
IO_METHOD(IoNumber,asNumber)364 IO_METHOD(IoNumber, asNumber)
365 {
366 	/*doc Number asNumber
367 	Returns self.
368 	*/
369 
370 	return self;
371 }
372 
IO_METHOD(IoNumber,add_)373 IO_METHOD(IoNumber, add_)
374 {
375 	/*doc Number +(aNumber)
376 	Returns a new number that is the sum of the receiver and aNumber.
377 	*/
378 
379 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
380 	return IONUMBER(DATA(self) + DATA(other));
381 }
382 
383 
IO_METHOD(IoNumber,subtract)384 IO_METHOD(IoNumber, subtract)
385 {
386 	/*doc Number -(aNumber)
387 	Returns a new number that is the difference of the receiver and aNumber.
388 	*/
389 
390 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
391 	return IONUMBER(DATA(self) - DATA(other));
392 }
393 
IO_METHOD(IoNumber,divide)394 IO_METHOD(IoNumber, divide)
395 {
396 	/*doc Number /(aNumber)
397 	Returns a new number with the value of the receiver divided by aNumber.
398 	*/
399 
400 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
401 	return IONUMBER(DATA(self) / DATA(other));
402 }
403 
IO_METHOD(IoNumber,multiply)404 IO_METHOD(IoNumber, multiply)
405 {
406 	/*doc Number *(aNumber)
407 	Returns a new number that is the product of the receiver and aNumber.
408 	*/
409 
410 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
411 	return IONUMBER(DATA(self) * DATA(other));
412 }
413 
IoNumber_asAllocedCString(IoNumber * self)414 char *IoNumber_asAllocedCString(IoNumber *self)
415 {
416 	int size = 1024;
417 	char *s = (char *)io_calloc(1, size);
418 	memset(s, 0, size);
419 	IoNumber_Double_intoCString_(DATA(self), s, size - 1);
420 	return s;
421 }
422 
IO_METHOD(IoNumber,printNumber)423 IO_METHOD(IoNumber, printNumber)
424 {
425 	/*doc Number print
426 	Prints the number.
427 	*/
428 
429 	char *s = IoNumber_asAllocedCString(self);
430 	IoState_print_((IoState *)IOSTATE, s);
431 	io_free(s);
432 	return self;
433 }
434 
IO_METHOD(IoNumber,justAsString)435 IO_METHOD(IoNumber, justAsString)
436 {
437 	IoSymbol *string;
438 	char *s = IoNumber_asAllocedCString(self);
439 	string = IoSeq_newWithCString_((IoState *)IOSTATE, s);
440 	io_free(s);
441 	return string;
442 }
443 
countBytes(long ld)444 static int countBytes(long ld)
445 {
446 	int n = 1;
447 	for (;;)
448 	{
449 		ld >>= 8;
450 		if (ld == 0)
451 		{
452 			return n;
453 		}
454 		n++;
455 	}
456 }
457 
IO_METHOD(IoNumber,asCharacter)458 IO_METHOD(IoNumber, asCharacter)
459 {
460 	/*doc Number asCharacter
461 	Returns a String containing a single character whose
462 	value is the value of the first byte of the receiver.
463 	Returns nil if the number has no valid UCS mapping.
464 	*/
465 
466 	double d =DATA(self);
467 	long ld = d;
468 
469 	if (d < 0 || d != ld)
470 	{
471 		return IONIL(self);
472 	}
473 	else
474 	{
475 		uint32_t i = io_uint32InBigEndian((uint32_t)d);
476 		int bytes = countBytes(ld);
477 		IoSeq *s;
478 
479 		if (bytes == 0)
480 		{
481 			bytes = 1;
482 		}
483 
484 		if (bytes == 3)
485 		{
486 			bytes = 4;
487 		}
488 
489 		if (bytes > 4)
490 		{
491 			// no valid UCS encoding for this value
492 			return IONIL(self);
493 		}
494 
495 		s = IoSeq_newWithData_length_(IOSTATE, (unsigned char *)&i, bytes);
496 
497 		{
498 			UArray *u = IoSeq_rawUArray(s);
499 			int e = CENCODING_ASCII;
500 
501 			switch (bytes)
502 			{
503 				case 1: e = CENCODING_ASCII; break;
504 				case 2: e = CENCODING_UCS2; break;
505 				case 4: e = CENCODING_UCS4; break;
506 			}
507 
508 			UArray_setEncoding_(u, e);
509 		}
510 
511 		return s;
512 	}
513 }
514 
IO_METHOD(IoNumber,asUint32Buffer)515 IO_METHOD(IoNumber, asUint32Buffer)
516 {
517 	/*doc Number asUint32Buffer
518 	Returns a Sequence containing a 4 byte representation of the uint32 value of the receiver.
519 	*/
520 
521 	uint32_t i = (int)DATA(self);
522 	return IoSeq_newWithData_length_(IOSTATE, (unsigned char *)&i, sizeof(uint32_t));
523 }
524 
IO_METHOD(IoNumber,asBuffer)525 IO_METHOD(IoNumber, asBuffer)
526 {
527 	/*doc Number asBuffer(optionalNumberOfBytes)
528 	Returns a Buffer containing a the number of bytes specified by
529 	optionalNumberOfBytes (up to the size of a double on the platform) of the receiver.
530 	If no optionalNumberOfBytes is specified, it is assumed to be the number of bytes
531 	in a double on the host platform.
532 	*/
533 	IoNumber *byteCount = IoMessage_locals_valueArgAt_(m, locals, 0);
534 	int bc = sizeof(double);
535 
536 	if (!ISNIL(byteCount))
537 	{
538 		bc = DATA(byteCount);
539 	}
540 	return IoSeq_newWithData_length_(IOSTATE, (unsigned char *)&(DATA(self)), bc);
541 }
542 
IO_METHOD(IoNumber,asString)543 IO_METHOD(IoNumber, asString)
544 {
545 /*doc Number asString(optionalIntegerDigits, optionalFactionDigits)
546 Returns a string representation of the receiver. For example:
547 <pre>
548 1234.5678 asString(0, 2)
549 </pre>
550 would return:
551 <pre>
552 1234.57
553 </pre>
554 */
555 
556 	if (IoMessage_argCount(m) >= 1)
557 	{
558 		int whole = IoMessage_locals_intArgAt_(m, locals, 0);
559 		int part = 6;
560 		char *s;
561 		size_t length;
562 		IoObject *n;
563 
564 
565 		if (IoMessage_argCount(m) >= 2)
566 		{
567 			part = abs(IoMessage_locals_intArgAt_(m, locals, 1));
568 		}
569 
570 		part  = abs(part);
571 		whole = abs(whole);
572 
573 		// If whole == 0, printf might need an arbitary size string. Instead of
574 		// second guessing the size, pick a really big size: 1024.
575 		length = 1024;
576 		s = io_calloc(1, length);
577 
578 		snprintf(s, length, "%*.*f", whole, part, DATA(self));
579 
580 		n = IOSEQ((unsigned char *)s, (size_t)strlen(s));
581 
582 		io_free(s);
583 
584 		return n;
585 	}
586 
587 	return IoNumber_justAsString(self, locals, m);
588 }
589 
590 /*
591 IO_METHOD(IoNumber, asDate)
592 {
593 	return IoDate_newWithNumber_((IoState *)IOSTATE, DATA(self));
594 }
595 */
596 
IO_METHOD(IoNumber,abs)597 IO_METHOD(IoNumber, abs)
598 {
599 	/*doc Number abs
600 	Returns a number with the absolute value of the receiver.
601 	*/
602 
603 	return (DATA(self) < 0) ? (IoObject *)IONUMBER(-DATA(self)) : (IoObject *)self;
604 }
605 
IO_METHOD(IoNumber,acos)606 IO_METHOD(IoNumber, acos)
607 {
608 	/*doc Number acos
609 	Returns a number with the arc cosine of the receiver.
610 	*/
611 
612 	return IONUMBER(acos(DATA(self)));
613 }
614 
IO_METHOD(IoNumber,asin)615 IO_METHOD(IoNumber, asin)
616 {
617 	/*doc Number asin
618 	Returns a number with the arc sine of the receiver.
619 	*/
620 
621 	return IONUMBER(asin(DATA(self)));
622 }
623 
IO_METHOD(IoNumber,atan)624 IO_METHOD(IoNumber, atan)
625 {
626 	/*doc Number atan
627 	Returns a number with the arc tangent of the receiver.
628 	*/
629 
630 	return IONUMBER(atan(DATA(self)));
631 }
632 
IO_METHOD(IoNumber,atan2)633 IO_METHOD(IoNumber, atan2)
634 {
635 	/*doc Number atan2(aNumber)
636 	Returns a number with the arc tangent of y/x where y is the receiver and x is aNumber.
637 	*/
638 
639 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
640 	return IONUMBER(atan2(DATA(self), DATA(other)));
641 }
642 
IO_METHOD(IoNumber,ceil)643 IO_METHOD(IoNumber, ceil)
644 {
645 	/*doc Number ceil
646 	Returns the a number with the receiver's value rounded up to
647 	the nearest integer if its fractional component is greater than 0.
648 	*/
649 
650 	return IONUMBER(ceil(DATA(self)));
651 }
652 
IO_METHOD(IoNumber,cos)653 IO_METHOD(IoNumber, cos)
654 {
655 	/*doc Number cos
656 	Returns the cosine of the receiver.
657 	*/
658 
659 	return IONUMBER(cos(DATA(self)));
660 }
661 
662 /*
663 IO_METHOD(IoNumber, deg)
664 {
665 	return IONUMBER(deg(DATA(self)));
666 }
667 */
668 
IO_METHOD(IoNumber,exp)669 IO_METHOD(IoNumber, exp)
670 {
671 	/*doc Number exp
672 	Returns e to the power of the receiver.
673 	*/
674 
675 	return IONUMBER(exp(DATA(self)));
676 }
677 
IO_METHOD(IoNumber,factorial)678 IO_METHOD(IoNumber, factorial)
679 {
680 	/*doc Number factorial
681 	Returns the factorial of the receiver.
682 	*/
683 
684 	int n = DATA(self);
685 	double v = 1;
686 	while (n)
687 	{
688 		v *= n;
689 		n--;
690 	}
691 	return IONUMBER(v);
692 }
693 
IO_METHOD(IoNumber,floor)694 IO_METHOD(IoNumber, floor)
695 {
696 	/*doc Number floor
697 	Returns a number with the receiver's value rounded
698 	down to the nearest integer if its fractional component is not 0.
699 	*/
700 
701 	return IONUMBER(floor(DATA(self)));
702 }
703 
IO_METHOD(IoNumber,log)704 IO_METHOD(IoNumber, log)
705 {
706 	/*doc Number log
707 	Returns the logarithm of the receiver.  The base
708 	is taken as the value of the first argument or the constant e if
709 	the first argument is omitted.
710 	*/
711 
712 	float base;
713 	if(IoMessage_argCount(m) > 0){
714 		base = DATA(IoMessage_locals_numberArgAt_(m, locals, 0));
715 	}
716 	else{
717 		base = (float)M_E;
718 	}
719 	return IONUMBER(log(DATA(self)) / log(base));
720 }
721 
IO_METHOD(IoNumber,log2)722 IO_METHOD(IoNumber, log2)
723 {
724 	/*doc Number log2
725 	Returns the base 2 logarithm of the receiver.
726 	*/
727 
728 	return IONUMBER(log2(DATA(self)));
729 }
730 
IO_METHOD(IoNumber,log10)731 IO_METHOD(IoNumber, log10)
732 {
733 	/*doc Number log10
734 	Returns the base 10 logarithm of the receiver.
735 	*/
736 
737 	return IONUMBER(log10(DATA(self)));
738 }
739 
IO_METHOD(IoNumber,max)740 IO_METHOD(IoNumber, max)
741 {
742 	/*doc Number max(aNumber)
743 	Returns the greater of the receiver and aNumber.
744 	*/
745 
746 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
747 	return (DATA(self) > DATA(other)) ? (IoObject *)self :(IoObject *)other;
748 }
749 
IO_METHOD(IoNumber,min)750 IO_METHOD(IoNumber, min)
751 {
752 	/*doc Number min(aNumber)
753 	Returns the lesser of the receiver and aNumber.
754 	*/
755 
756 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
757 	return (DATA(self) < DATA(other)) ? (IoObject *)self : (IoObject *)other;
758 }
759 
IO_METHOD(IoNumber,mod)760 IO_METHOD(IoNumber, mod)
761 {
762 	/*doc Number %(aNumber)
763 	Returns the receiver modulus aNumber.
764 	*/
765 
766 	/*doc Number mod(aNumber)
767 	Returns the receiver modulus aNumber.
768 	*/
769 
770 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
771 	return IONUMBER(fmod(DATA(self), DATA(other)));
772 }
773 
774 /*
775 IO_METHOD(IoNumber, modf)
776 {
777 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
778 	if (DATA(self) < DATA(other)); return self;
779 	return other;
780 }
781 
782 IO_METHOD(IoNumber, rad)
783 */
784 
IO_METHOD(IoNumber,pow)785 IO_METHOD(IoNumber, pow)
786 {
787 	/*doc Number pow(aNumber)
788 	Returns the value of the receiver to the aNumber power.
789 	*/
790 
791 	/*doc Number **(aNumber)
792 	Same as pow(aNumber).
793 	*/
794 
795 	IoNumber *other = IoMessage_locals_numberArgAt_(m, locals, 0);
796 	return IONUMBER(pow(DATA(self), DATA(other)));
797 }
798 
IO_METHOD(IoNumber,round)799 IO_METHOD(IoNumber, round)
800 {
801 	/*doc Number round
802 	Returns a number with the receiver's value rounded up to
803 	the nearest integer if its fraction component is >= .5 or rounded up to the nearest integer otherwise.
804 	*/
805 
806 	double x = DATA(self);
807 	if (x < 0.0)
808 		return IONUMBER(ceil(x - 0.5));
809 	else
810 		return IONUMBER(floor(x + 0.5));
811 }
812 
IO_METHOD(IoNumber,roundDown)813 IO_METHOD(IoNumber, roundDown)
814 {
815 	/*doc Number roundDown
816 	Returns a number with the receiver's value rounded down to
817 	the nearest integer if its fraction component is <= .5 or rounded up the the nearest integer otherwise.
818 	*/
819 
820 	return IONUMBER(floor(DATA(self) + 0.5));
821 }
822 
IO_METHOD(IoNumber,sin)823 IO_METHOD(IoNumber, sin)
824 {
825 	/*doc Number sin
826 	Returns the sine of the receiver.
827 	*/
828 
829 	return IONUMBER(sin(DATA(self)));
830 }
831 
IO_METHOD(IoNumber,sqrt)832 IO_METHOD(IoNumber, sqrt)
833 {
834 	/*doc Number sqrt
835 	Returns the square root of the receiver.
836 	*/
837 
838 	return IONUMBER(sqrt(DATA(self)));
839 }
840 
IO_METHOD(IoNumber,squared)841 IO_METHOD(IoNumber, squared)
842 {
843 	/*doc Number squared
844 	Returns the square of the receiver.
845 	*/
846 
847 	double v = DATA(self);
848 	return IONUMBER(v * v);
849 }
850 
IO_METHOD(IoNumber,cubed)851 IO_METHOD(IoNumber, cubed)
852 {
853 	/*doc Number cubed
854 	Returns the cube of the receiver.
855 	*/
856 
857 	double v = DATA(self);
858 	return IONUMBER(v * v * v);
859 }
860 
861 
IO_METHOD(IoNumber,tan)862 IO_METHOD(IoNumber, tan)
863 {
864 	/*doc Number tan
865 	Returns the tangent of the receiver.
866 	*/
867 
868 	return IONUMBER(tan(DATA(self)));
869 }
870 
871 /*
872 IO_METHOD(IoNumber, frexp)
873 {
874 	return IONUMBER( frexp(DATA(self)) );
875 }
876 
877 IO_METHOD(IoNumber, ldexp)
878 {
879 	return IONUMBER( ldexp(DATA(self)) );
880 }
881 */
882 
IO_METHOD(IoNumber,toggle)883 IO_METHOD(IoNumber, toggle)
884 {
885 	/*doc Number toggle
886 	Returns 1 if the receiver is 0. Returns 0 otherwise.
887 	*/
888 
889 	return (DATA(self))? (IoObject *)IONUMBER(0) : (IoObject *)IONUMBER(1);
890 }
891 
892 /* --- bitwise operations ---------------------------------------- */
893 
IO_METHOD(IoNumber,bitwiseAnd)894 IO_METHOD(IoNumber, bitwiseAnd)
895 {
896 	/*doc Number &(aNumber)
897 	Returns a new number with the bitwise AND of the receiver and aNumber.
898 	*/
899 
900 	/*doc Number bitwiseAnd(aNumber)
901 	Returns a new number with the bitwise AND of the receiver and aNumber.
902 	*/
903 
904 	long other = IoMessage_locals_longArgAt_(m, locals, 0);
905 	return IONUMBER(((long)DATA(self) & other));
906 }
907 
IO_METHOD(IoNumber,bitwiseOr)908 IO_METHOD(IoNumber, bitwiseOr)
909 {
910 	/*doc Number |(aNumber)
911 	Returns a new number with the bitwise OR of the receiver and aNumber.
912 	*/
913 
914 	/*doc Number bitwiseOr(aNumber)
915 	Returns a new number with the bitwise AND of the receiver and aNumber.
916 	*/
917 
918 	long other = IoMessage_locals_longArgAt_(m, locals, 0);
919 	long n = DATA(self);
920 	long r = n | other;
921 	return IONUMBER(r);
922 }
923 
IO_METHOD(IoNumber,bitwiseXor)924 IO_METHOD(IoNumber, bitwiseXor)
925 {
926 	/*doc Number bitwiseXor(aNumber)
927 	Returns a new number with the bitwise XOR of the receiver and aNumber.
928 	*/
929 
930 	/*doc Number ^(aNumber)
931 	Returns the bitwise xor with the receiver (both numbers are converted to longs for the operation).
932 	*/
933 
934 	long other = IoMessage_locals_longArgAt_(m, locals, 0);
935 	long r = (double)((long)DATA(self) ^ other);
936 	return IONUMBER(r);
937 }
938 
IO_METHOD(IoNumber,bitwiseComplement)939 IO_METHOD(IoNumber, bitwiseComplement)
940 {
941 	/*doc Number bitwiseComplement
942 	Returns a new number with the bitwise complement of the
943 	receiver. (The 0 bits become 1s and the 1 bits become 0s. )
944 	*/
945 
946 	long r = (double)(~(long)DATA(self));
947 	return IONUMBER(r);
948 }
949 
IO_METHOD(IoNumber,bitShiftLeft)950 IO_METHOD(IoNumber, bitShiftLeft)
951 {
952 	/*doc Number <<(aNumber)
953 	Shifts the bits of the receiver left by the number of places specified by aNumber.
954 	*/
955 
956 	long other = IoMessage_locals_longArgAt_(m, locals, 0);
957 	long r = (double)((long)DATA(self) << other);
958 	return IONUMBER(r);
959 }
960 
IO_METHOD(IoNumber,bitShiftRight)961 IO_METHOD(IoNumber, bitShiftRight)
962 {
963 	/*doc Number >>(aNumber)
964 	Shifts the bits of the receiver right by the number of places specified by aNumber.
965 	*/
966 
967 	long other = IoMessage_locals_longArgAt_(m, locals, 0);
968 	long r =  (double)((long)DATA(self) >> (long)other);
969 	return IONUMBER(r);
970 }
971 
972 // even and odd ------------------------------
973 
IO_METHOD(IoNumber,isEven)974 IO_METHOD(IoNumber, isEven)
975 {
976 	/*doc Number isEven
977 	Returns true if
978 	integer form of the receiver is even
979 	, false otherwise.
980 	*/
981 
982 	int n = DATA(self);
983 	return IOBOOL(self, 0 == (n & 0x01));
984 }
985 
IO_METHOD(IoNumber,isOdd)986 IO_METHOD(IoNumber, isOdd)
987 {
988 	/*doc Number isOdd
989 	Returns true if
990 	integer form of the receiver is odd
991 	, false otherwise.
992 	*/
993 
994 	int n = DATA(self);
995 	return IOBOOL(self, 0x01 == (n & 0x01));
996 }
997 
998 // character operations ---------------------------------
999 
IO_METHOD(IoNumber,isAlphaNumeric)1000 IO_METHOD(IoNumber, isAlphaNumeric)
1001 {
1002 	/*doc Number isAlphaNumeric
1003 	Returns true if
1004 	receiver is an alphanumeric character value
1005 	, false otherwise.
1006 	*/
1007 
1008 	return IOBOOL(self, isalnum((int)DATA(self)));
1009 }
1010 
IO_METHOD(IoNumber,isLetter)1011 IO_METHOD(IoNumber, isLetter)
1012 {
1013 	/*doc Number isLetter
1014 	Returns true if
1015 	receiver is a letter character value
1016 	, false otherwise.
1017 	*/
1018 
1019 	return IOBOOL(self, isalpha((int)DATA(self)));
1020 }
1021 
IO_METHOD(IoNumber,isControlCharacter)1022 IO_METHOD(IoNumber, isControlCharacter)
1023 {
1024 	/*doc Number isControlCharacter
1025 	Returns true if
1026 	receiver is a control character value
1027 	, false otherwise.
1028 	*/
1029 
1030 	return IOBOOL(self, iscntrl((int)DATA(self)));
1031 }
1032 
IO_METHOD(IoNumber,isDigit)1033 IO_METHOD(IoNumber, isDigit)
1034 {
1035 	/*doc Number isDigit
1036 	Returns true if
1037 	receiver is a numeric digit value
1038 	, false otherwise.
1039 	*/
1040 
1041 	return IOBOOL(self, isdigit((int)DATA(self)));
1042 }
1043 
IO_METHOD(IoNumber,isGraph)1044 IO_METHOD(IoNumber, isGraph)
1045 {
1046 	/*doc Number isGraph
1047 	Returns true if
1048 	the receiver is a printing character value except space
1049 	, false otherwise.
1050 	*/
1051 
1052 	return IOBOOL(self, isgraph((int)DATA(self)));
1053 }
1054 
IO_METHOD(IoNumber,isLowercase)1055 IO_METHOD(IoNumber, isLowercase)
1056 {
1057 	/*doc Number isLowercase
1058 	Returns true if
1059 	the receiver is a lowercase character value
1060 	, false otherwise.
1061 	*/
1062 
1063 	return IOBOOL(self, islower((int)DATA(self)));
1064 }
1065 
IO_METHOD(IoNumber,isUppercase)1066 IO_METHOD(IoNumber, isUppercase)
1067 {
1068 	/*doc Number isUppercase
1069 	Returns true if
1070 	the receiver is a uppercase character value
1071 	, false otherwise.
1072 	*/
1073 
1074 	return IOBOOL(self, isupper((int)DATA(self)));
1075 }
1076 
IO_METHOD(IoNumber,isPrint)1077 IO_METHOD(IoNumber, isPrint)
1078 {
1079 	/*doc Number isPrint
1080 	Returns true if
1081 	the receiver is a printing character value, including space
1082 	, false otherwise.
1083 	*/
1084 
1085 	return IOBOOL(self, isprint((int)DATA(self)));
1086 }
1087 
IO_METHOD(IoNumber,isPunctuation)1088 IO_METHOD(IoNumber, isPunctuation)
1089 {
1090 	/*doc Number isPunctuation
1091 	Returns true if
1092 	the receiver is a punctuation character value
1093 	, false otherwise.
1094 
1095 	*/
1096 
1097 	return IOBOOL(self, ispunct((int)DATA(self)));
1098 }
1099 
IO_METHOD(IoNumber,isSpace)1100 IO_METHOD(IoNumber, isSpace)
1101 {
1102 	/*doc Number isSpace
1103 	Returns true if
1104 	the receiver is a space, formfeed, newline carriage return, tab or vertical tab character value
1105 	, false otherwise.
1106 	*/
1107 
1108 	return IOBOOL(self, isspace((int)DATA(self)));
1109 }
1110 
IO_METHOD(IoNumber,isHexDigit)1111 IO_METHOD(IoNumber, isHexDigit)
1112 {
1113 	/*doc Number isHexDigit
1114 	Returns true if
1115 	the receiver is a hexadecimal character value
1116 	, false otherwise.
1117 	*/
1118 
1119 	return IOBOOL(self, isxdigit((int)DATA(self)));
1120 }
1121 
1122 // case ---------------------------------
1123 
IO_METHOD(IoNumber,asLowercase)1124 IO_METHOD(IoNumber, asLowercase)
1125 {
1126 	/*doc Number asLowercase
1127 	Returns a new Number containing a lower case version of the receiver.
1128 	*/
1129 
1130 	int r = tolower((int)DATA(self));
1131 	return IONUMBER(r);
1132 }
1133 
IO_METHOD(IoNumber,asUppercase)1134 IO_METHOD(IoNumber, asUppercase)
1135 {
1136 	/*doc Number asUppercase
1137 	Returns a new Number containing a upper case version of the receiver.
1138 	*/
1139 
1140 	int r = toupper((int)DATA(self));
1141 	return IONUMBER(r);
1142 }
1143 
IO_METHOD(IoNumber,between)1144 IO_METHOD(IoNumber, between)
1145 {
1146 	/*doc Number between(aNumber1, aNumber2)
1147 	Returns true if the receiver's value is between or
1148 	equal to aNumber1 and aNumber2, otherwise returns false.
1149 	*/
1150 
1151 	double a = IoMessage_locals_doubleArgAt_(m, locals, 0);
1152 	double b = IoMessage_locals_doubleArgAt_(m, locals, 1);
1153 	double n = DATA(self);
1154 
1155 	return IOBOOL(self, ((n >= a) && (n <= b)) || (n <= a && (n >= b)));
1156 }
1157 
IO_METHOD(IoNumber,clip)1158 IO_METHOD(IoNumber, clip)
1159 {
1160 	/*doc Number clip(aNumber1, aNumber2)
1161 	Returns self if the receiver is between aNumber1 and aNumber2.
1162 	Returns aNumber1 if it is less than aNumber1. Returns aNumber2 if it is greater than aNumber2.
1163 	*/
1164 
1165 	double a = IoMessage_locals_doubleArgAt_(m, locals, 0);
1166 	double b = IoMessage_locals_doubleArgAt_(m, locals, 1);
1167 	double n = DATA(self);
1168 
1169 	if (n < a) n = a;
1170 	if (n > b) n = b;
1171 
1172 	return IONUMBER(n);
1173 }
1174 
IO_METHOD(IoNumber,negate)1175 IO_METHOD(IoNumber, negate)
1176 {
1177 	/*doc Number negate
1178 	Returns new number that is negated version of the receiver.
1179 	*/
1180 
1181 	return IONUMBER(-DATA(self));
1182 }
1183 
IO_METHOD(IoNumber,at)1184 IO_METHOD(IoNumber, at)
1185 {
1186 	/*doc Number at(bitIndexNumber)
1187 	Returns a new Number containing 1 if the receiver cast to a long
1188 	has its bit set to 1 at bitIndexNumber. Otherwise returns 0.
1189 	*/
1190 
1191 	int i = IoMessage_locals_intArgAt_(m, locals, 0);
1192 	long l = (long)DATA(self);
1193 
1194 	IOASSERT((i >= 0) && (i < sizeof(double)*8), "index out of bit bounds");
1195 
1196 	l = l >> i;
1197 	l = l & 0x1;
1198 	return IONUMBER(l);
1199 }
1200 
1201 // limits ------------------------------------
1202 
IO_METHOD(IoNumber,integerMax)1203 IO_METHOD(IoNumber, integerMax)
1204 {
1205 	/*doc Number integerMax
1206 	Returns the maximum integer value.
1207 	*/
1208 
1209 	return IONUMBER(INT_MAX);
1210 }
1211 
IO_METHOD(IoNumber,integerMin)1212 IO_METHOD(IoNumber, integerMin)
1213 {
1214 	/*doc Number integerMin
1215 	Returns the minimum integer value.
1216 	*/
1217 
1218 	return IONUMBER(INT_MIN);
1219 }
1220 
1221 
IO_METHOD(IoNumber,longMax)1222 IO_METHOD(IoNumber, longMax)
1223 {
1224 	/*doc Number longMax
1225 	Returns the maximum long value.
1226 	*/
1227 
1228 	return IONUMBER(LONG_MAX);
1229 }
1230 
IO_METHOD(IoNumber,longMin)1231 IO_METHOD(IoNumber, longMin)
1232 {
1233 	/*doc Number longMin
1234 	Returns the minimum long value.
1235 	*/
1236 
1237 	return IONUMBER(LONG_MIN);
1238 }
1239 
1240 
IO_METHOD(IoNumber,shortMax)1241 IO_METHOD(IoNumber, shortMax)
1242 {
1243 	/*doc Number shortMax
1244 	Returns the maximum short value.
1245 	*/
1246 
1247 	return IONUMBER(SHRT_MAX);
1248 }
1249 
IO_METHOD(IoNumber,shortMin)1250 IO_METHOD(IoNumber, shortMin)
1251 {
1252 	/*doc Number shortMin
1253 	Returns the minimum short value.
1254 	*/
1255 
1256 	return IONUMBER(SHRT_MIN);
1257 }
1258 
IO_METHOD(IoNumber,unsignedLongMax)1259 IO_METHOD(IoNumber, unsignedLongMax)
1260 {
1261 	/*doc Number unsignedLongMax
1262 	Returns the maximum unsigned long value.
1263 	*/
1264 
1265 	return IONUMBER(ULONG_MAX);
1266 }
1267 
IO_METHOD(IoNumber,unsignedIntMax)1268 IO_METHOD(IoNumber, unsignedIntMax)
1269 {
1270 	/*doc Number unsignedIntMax
1271 	Returns the maximum unsigned int value.
1272 	*/
1273 
1274 	return IONUMBER(UINT_MAX);
1275 }
1276 
IO_METHOD(IoNumber,unsignedShortMax)1277 IO_METHOD(IoNumber, unsignedShortMax)
1278 {
1279 	/*doc Number unsignedShortMax
1280 	Returns the minimum unsigned int value.
1281 	*/
1282 
1283 	return IONUMBER(USHRT_MAX);
1284 }
1285 
IO_METHOD(IoNumber,floatMax)1286 IO_METHOD(IoNumber, floatMax)
1287 {
1288 	/*doc Number floatMax
1289 	Returns the maximum float value.
1290 	*/
1291 
1292 	return IONUMBER(FLT_MAX);
1293 }
1294 
IO_METHOD(IoNumber,floatMin)1295 IO_METHOD(IoNumber, floatMin)
1296 {
1297 	/*doc Number floatMin
1298 	Returns the minimum float value.
1299 	*/
1300 
1301 	return IONUMBER(FLT_MIN);
1302 }
1303 
IO_METHOD(IoNumber,doubleMax)1304 IO_METHOD(IoNumber, doubleMax)
1305 {
1306 	/*doc Number floatMax
1307 	Returns the maximum double precision float value.
1308 	*/
1309 
1310 	return IONUMBER(DBL_MAX);
1311 }
1312 
IO_METHOD(IoNumber,doubleMin)1313 IO_METHOD(IoNumber, doubleMin)
1314 {
1315 	/*doc Number doubleMin
1316 	Returns the minimum double precision float value.
1317 	*/
1318 
1319 	return IONUMBER(DBL_MIN);
1320 }
1321 
IO_METHOD(IoNumber,isNan)1322 IO_METHOD(IoNumber, isNan)
1323 {
1324 	/*doc Number isNan
1325 	Returns true if the receiver is not a number. Otherwise returns false.
1326 	*/
1327 
1328 	return IOBOOL(self, isnan(CNUMBER(self)));
1329 }
1330 
1331 // looping ---------------------------------------------
1332 
IO_METHOD(IoNumber,repeat)1333 IO_METHOD(IoNumber, repeat)
1334 {
1335 	/*doc Number repeat(optionalIndex, expression)
1336 	Evaluates message a number of times that corresponds to the receivers
1337 	integer value. This is significantly faster than a for() or while() loop.
1338 	*/
1339 
1340 	IoMessage_assertArgCount_receiver_(m, 1, self);
1341 
1342 	{
1343 		IoState *state = IOSTATE;
1344 		IoSymbol *indexSlotName;
1345 		IoMessage *doMessage;
1346 		double i, max = CNUMBER(self);
1347 		IoObject *result = IONIL(self);
1348 
1349 		if(IoMessage_argCount(m) > 1)
1350 		{
1351 			indexSlotName = IoMessage_name(IoMessage_rawArgAt_(m, 0));
1352 			doMessage = IoMessage_rawArgAt_(m, 1);
1353 		}
1354 		else
1355 		{
1356 			indexSlotName = 0;
1357 			doMessage = IoMessage_rawArgAt_(m, 0);
1358 		}
1359 
1360 		IoState_pushRetainPool(state);
1361 
1362 		for (i = 0; i < max; i ++)
1363 		{
1364 			/*
1365 			if (result != locals && result != self)
1366 			{
1367 				IoState_immediatelyFreeIfUnreferenced_(state, result);
1368 			}
1369 			*/
1370 
1371 			IoState_clearTopPool(state);
1372 
1373 			if (indexSlotName)
1374 			{
1375 				IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i));
1376 			}
1377 
1378 			result = IoMessage_locals_performOn_(doMessage, locals, locals);
1379 
1380 			if (IoState_handleStatus(IOSTATE))
1381 			{
1382 				break;
1383 			}
1384 		}
1385 
1386 		IoState_popRetainPoolExceptFor_(IOSTATE, result);
1387 		return result;
1388 	}
1389 }
1390 
1391