2009年10月29日星期四

准命令行编译Flash

0 comments
没用过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

0 comments
诡异事件的出现,多数是由于对其了解不够多。
本来在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日星期一

八小时里的那点儿事儿

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

2009年9月10日星期四

Be Careful

0 comments
连续两天到客户现场去测试程序,由开发、测试、技术支持三队人马一起行动。显然,这种情况需要事先安排好计划,到了现场以后才可能有条不紊的进行工作,否则,只能是一团糟或者延误时间。

今天自己犯了一个太大的错误,在现场以为数据库里都是些测试数据,直接把某个表的数据全部UPDATE成了初始状态,谁知里面有一万多条客户真实数据,幸好客户的这批任务已全部结束,否则不堪设想。事情虽然没有产生什么恶性后果,但这样的错误难以忍受。以后做类似操作,一定要确保头脑清醒,且谨慎!

2009年8月31日星期一

To be, or not to be

0 comments

我写了一些自动化脚本,为了在C/S结构软件中编写服务端时,有个客户端可以自已运行,省得一心二用,左顾右盼。我自己用到开发过程中,这个小东西效果很好,省了很多事。
它看起来确实不错呀,项目组长发现了,推荐给测试人员吧。我摇身一变,从开发变成测试开发了。但是GUI测试确实烦人呀,好歹将就着能用了,我真希望到此为止吧。但是,用户的需求是不断的,然而,我希望这些工作应该是由测试人员来做的。因为,工具只是辅助工作的,只有使用他的人才知道怎么最有效。
不能说服别人做好,如果真的做的好,别人自然会按你做的来;同样,我也不希望把东西做好了送到别人跟前让人承认这是好东西。

我把桌面的AutoIt背景换掉了,到此为止。附加的一个原因是,没有发现AutoIt中动态调用函数的方式,再做更多工作需要的代价过高了。

2009年8月18日星期二

WTL及其他

0 comments

WTL有更新了,8.1,在VS2008中安装Wizard时再也不会复制-打开-替换-保存-关闭操作了。
WTL程序中,包含ActiveX控件要导入类型库,在stdafx.h中加入
#import "c:/windows/system32/wmp.dll" raw_interfaces_only, raw_native_types, no_namespace, named_guids
Flash控件可能不在system32下了,跑到Macromed中的某个地方了。

包含RichEdit控件,要在创建前进行
HINSTANCE hInstRich = ::LoadLibrary(CRichEditCtrl::GetLibraryName());
ATLASSERT(hInstRich != NULL);
否则主窗体创建失败。 
结束前
::FreeLibrary(hInstRich); 

Subversion也支持external文件了,但是还存在已知问题,所以多数时候还是没用,因为我想external的多数是二进制文件。

好长时间没注意,FOP也更新到0.95了。

2009年8月12日星期三

DON'T DO THIS

0 comments

Delphi的帮助中有一个条目是Returning a PChar local variable,当然这个条目说的是反例,是说长字符串与PChar之间的差别会引起的问题。在这个条目中所举的例子里,特别注释了“// DON'T DO THIS”,但是正如这一条目开头便指出的,这却是一个常见的错误,所以这样写法还是屡见不鲜,而且通常看起来也似乎正确,但是,并不是这样的。

function ReturnLocalStringToPChar: PChar;
   var S, Y: string;
   begin
      S := 'aaa';
      Y := 'bbb';
      S := S + Y;
      Result := PChar(S);
   end;

   procedure Test(S: string)
   var
     A: string;
     P: PChar;
  begin
     P := ReturnLocalStringToPChar;
     WriteLn(P);
     A := GetCurrentDir;
     WriteLn(P);
  end;

如果你认为两次打印的内容是一样的,那就错了。

所以,文档是一定要看的。想起邮件列表中有人回答问题的同时说不知道为什么很多人不看文档,而他对很熟悉的东西也是要常翻翻文档的。
同样,在前几天,在同别人调试AutoIt3脚本时,发现因为没有看到最新的文档,对返回值的判断不正确的情况。

看清楚文档,用明确知道的东西,知道自己在写什么,才可能写出可靠的代码。

2009年7月17日星期五

Out of Memory 就这样崩溃

0 comments
一年多的短信从来没有删除过,手机终于崩溃了,任何动作都提示空间不足。
我也一样,一年过去了,就这样静静的崩溃,做不出任何动作。
Formatting的是手机。格式化的是我。
无声无息。无知无觉。

行动 Just Do It

0 comments
行动是最重要的。今天被自己的行为教育了。
半年前,为了熟悉HMM,将别人的一个英文词性标注器用Python实现了一遍,无非是在C++和Python间翻译代码。可是,翻译完了一测试,准确率不足70%,毫无疑问,肯定是自己的实现某处有不显眼的错误。当时没有找出问题所在,后来多次打算把这个调试好,以备后用,但每次瞅几眼那些代码就困意重重而作罢。今天中午终于打定主意,仔细调试了一遍代码,不到二十分钟就找出来了问题,修改后已知词准确率98%。其实,跟以前相比,差别就是多了一点儿行动与耐心。
想起一位科学家谈到自己的重大发现时轻描淡写的说,只要做实验,谁都能看到。
只有行动才可能有结果;只有付出才可能有收获。

2009年5月14日星期四

南京小聚

0 comments
几个人从不同的方向到南京,不顾劳累,放弃游玩,来小聚一场。

上学时起租房的老朋友已几年不见,饭桌上突然说起魔方的时候,只以为是他一贯的调侃作风;当他真的从背包里拿出 Rublk's Cube 的时候,我也笑着拿出了自己的魔方,我们再一次握手。



南京几位东家的盛情款待让我感到情意的深厚,这是多么难得的开心时刻。


边走边看

 

Unbuilt Heaven. Copyright 2008 All Rights Reserved.  Revolution Two Church theme by Brian Gardner Converted into Blogger Template by Bloganol dot com