1. 程式人生 > >抓狂!!對浮點數使用 abs() 函式求絕對值的代價!!

抓狂!!對浮點數使用 abs() 函式求絕對值的代價!!

因程式需要,需求出浮點數的絕對值~

第一個想到的函式就是 abs(),不料無論怎麼求,abs出來的結果都是0!!

是的,就是0!!

真是他媽的太奇怪了,我檢查了一遍又一遍,程式碼的寫法沒有發現任何的問題,

可以求出來的結果他媽的就是0!!!

白白浪費了哥1個半小時以上,不瀉瀉火還真是他媽的受不了!!

這次我是真的學乖了,今後不管遇到了什麼問題,10分鐘每搞出來馬上去google查!!

不過也得到了一些意外的收穫,那就是我寫的那塊兒原來沒我想地那麼複雜,

基本上,求浮點數絕對值地問題解決了以後,將遊戲安裝到機器上得到地效果已經是相當地棒了。。

一句話,問題解決了就好。。。其實這次犯在這個問題上面還是怪自己太執拗,想當然~

總結一些,以下是從其他網站上面得到地一些新知識:

Question:

How do I convert a negative number to an absolute value in Objective-C?

i.e.

-10

becomes

10?

Answer:

Depending on the type of your variable, one of

 abs(int),

 labs(long),

 llabs(long long),

imaxabs(intmax_t),

 fabsf(float),

 fabs(double), or

 fabsl(long double)

.

(Alas, there is no habs(short) function. Or scabs(signed char) for that matter...)

下面粘上我更正之後地程式碼,可以試著將程式碼中的 fabsf 替換成 abs,可以得到截然不同的結果

-(void) setShapes:(NSMutableArray*)shapes {
	_shapes = shapes;
	int startX = 360;
	int deltaX = 40;
	int i = 0;
	int distance2center = 0;
	BOOL flag = YES;
	for(BYShape *shape in _shapes) {
		CCSprite *sprite = [shape getSprite];
		int w = sprite.contentSize.width;	// 形狀的寬度~
		int h = sprite.contentSize.height;	// 形狀的高度~
		float rotateRadians = CC_DEGREES_TO_RADIANS(-sprite.rotation);
		
		float absCosTheta = fabsf(cos(rotateRadians));
		float absSinTheta = fabsf(sin(rotateRadians));
		
		// w,h只能取得sprite未經任何處理時的高度和寬度,旋轉之後,新的寬度和高度需要經過重新計算獲得~
		// 矩形旋轉後的實際寬度和高度可由以下公式獲得:
		// width = w * abs(cos(theta)) + h * abs(sin(theta))
		// height = h * abs(cos(theta)) + w * abs(sin(theta))
//		float actualWidth = w * absCosTheta + h * absSinTheta;
		float actualHeight = h * absCosTheta + w * absSinTheta;
		
		float transformRatio = (float)TOOL_BAR_HEIGHT / actualHeight;	// 比率~
		
		if(transformRatio > 1.0f) {	// 如果形狀本身的高度就小於 TOOL_BAR_HEIGHT 的話,不進行任何放縮以避免畫質降低~
			transformRatio = 1.0f;
		}
		
		// 保留1位小數
//		NSString *reserveOneFloatPart = [NSString stringWithFormat:@"%0.1f", transformRatio];
//		transformRatio = [reserveOneFloatPart floatValue];
//		NSLog(@"保留1位小數: %.2f", transformRatio);
		
		sprite.position = ccp(startX + deltaX * i, 460);
		[sprite runAction:[CCScaleTo actionWithDuration:0.0f scale:transformRatio]];
				
		int spriteHalfWidth = sprite.contentSize.width * transformRatio / 2;
		if(i == 0) {	// 必須的(之前形狀向中間移動的時候對不齊原因就在於沒加上這句程式碼)!!!
			// 竟然會出現 transformRatio 和 sprite.scale 不相等的情況,奇葩(可能源於資料還未同步過來)~
			_previousShapeHalfWidth = spriteHalfWidth;	// 第一個形狀的一半寬度
		}
		
		if(flag == YES) {
			flag = NO;
		} else {
			distance2center += spriteHalfWidth;
			distance2center += TOOL_BAR_INTERVAL;	// 兩個形狀之間的間隔距離~
		}
		float distance = 160.0f + distance2center;
		[sprite runAction:[CCMoveTo actionWithDuration:0.6f position:ccp(distance, 460.0f)]];
		distance2center += spriteHalfWidth;
		i += 1;
		[self addChild:sprite];
	}
}