2009年10月29日星期四

准命令行编译Flash

没用过Flash,但是项目中有Flash的工程,当然希望Flash的编译成为自动构建的一部分。
本来以为可以用Flex SDK来搞定的,但是构建人员没有搞出来,只好回归到jsfl先用这准命令行的方式吧。
还是先放代码

//demo.jsfl
var doc = fl.openDocument("file:///c:/demo.fla");
doc.exportSWF("file:///c:/demo.swf", true);
fl.quit(false);

再加个命令行
flash.exe demo.jsfl 

有些时候,简单解决问题就好。

Invalid floating point operation

诡异事件的出现,多数是由于对其了解不够多。
本来在C++中调用多次的dll,放到Delphi中调用,总是产生“”Invalid floating point operation”异常,很是诧异。
多方搜索,原来要关闭浮点异常。

先放一段Delphi帮助中的例子,恐怕有很多人忘了用完之后设置回去。
procedure NumericExample;
var
  Saved8087CW: Word;
begin
  Saved8087CW := Default8087CW;
  Set8087CW($133f); { Disable all fpu exceptions }
  ThirdPartyRoutine;
  Set8087CW(Saved8087CW);
end;

Delphi帮助中的关于Set8087CW的说明,被我重新编排了一下引用如下(三段话,顺序正好与原来相反)。
It is recommended that you disable all floating-point exceptions when using OpenGL to render 3D graphics. To do this, call Set8087CW(0x133f) in your main form� OnCreate event before calling any OpenGL functions.
This routine allows the programmer to have direct access to the CW. Be aware that using this routine to change the value of the 8087CW will change the behavior of the program� FP calculations. It is the programmer's responsibility to reset it.
The floating-point unit control word controls the precision of floating point calculations, the rounding mode, and whether certain floating-point operations trigger exceptions. See Intel's processor documentation for details.
 
再放一段搜索来的内容增加长度。
Tripping floating-point exceptions
Floating-point exceptions are, as you might expect by virtue of the name, rare. The ones that happen most commonly by mistake in my experience are the zero-divide and invalid operation exceptions. Zero divide tends to happen whenever you have an unchecked normalization operation, such as resetting a 2D or 3D vector to unit length — which works fine, until someone hands you a vector of length zero. Another example would be trying to normalize a portion of audio that was totally silent. When the zero-divide exception is masked, the FPU spits out a signed infinity instead, which sometimes works out in the end. For instance, if the expression is of the form |x/y| > n, then the infinity would give you the correct result.
Invalid operation exceptions are more serious and result from operations that don't have a graceful way to degrade, such as 0/0, the square root of -1, etc. These too often result from the lack of bounds checks. For instance, a common way to determine the angle between two vectors is through dot product, since the shortest angle between two vectors is acos(dot(v1 / |v1|, v2 / |v2|)). Unfortunately, the common way of normalizing vectors is to multiply by the reciprocal square root of the squared length (dot(v,v)), which can give you a not-quite-unit-length vector since the squaring operation discards half of the usual precision. This can then lead to taking the arccosine of a number slightly larger than 1. When such an operation occurs and invalid operation exceptions are masked, the FPU spits out a Not a Number (NaN) value and keeps going. You can also trip such an exception by trying to operate on NaNs, especially by loading garbage data that isn't a valid IEEE finite number.
In general, you don't want to be tripping floating-point exceptions, even if they are masked. The reason is that when the FPU hits one, the fast hardware can't handle it and punts to the microcode, which then takes about twenty times longer. This is especially bad with NaNs since any operation with a NaN produces another NaN, causing them to spread throughout your calculations (NaN disease) and slow down everything massively. You can even crash due to NaNs blowing past clamp expressions, since any comparison with a NaN is false and converting one to integer form results in integer indefinite (0x80000000). Despite the erroneous results, though, NaNs can appear sporadically in a large Win32 program without anyone knowing, and may go unnoticed in a code base for years.
Note that although exceptions are really slow and usually indicate mistakes, the results when the exceptions are masked are well-defined. It is possible, and sometimes reasonable, to actually depend on and test for specific results from masked exceptions. So it isn't valid to simply say "don't do that."

 

2009年10月26日星期一

八小时里的那点儿事儿

又开始一个新项目了,工期不会超过两个月,代码不过万把行。
每个项目都是所谓工期短,时间紧,公司领导很重视。结果就是造就了一堆没人用的小玩意儿。
每个产品后期都会随着一次次的产品评审改来改去,其实那最应该叫做需求评审。
每个领导都有自己的想法,会对产品提出改进意见,但是,如果一个领导需要为界面上的几个普通的元素亲自负责的话,那是不是应该先招聘几个设计师呢。
每次例会都是以这些问题很重要开始,以这些问题会后讨论结束。