tim-wu

lucene的8位small float有bug? 跪求数学高手指教:)

今天翻了util包,发现自己对float的匮乏知识,好在有伟大的wiki百科:
http://en.wikipedia.org/wiki/IEEE_754
很清楚得解释了IEEE 754规范

可惜看不懂lucene对small float的结构定义。
如果按我的理解,似乎类SmallFloat的函数byteToFloat()和byte315ToFloat()有bug,通过编写测试代码:
SmallFloat.byte315ToFloat(Byte.parseByte("01111000", 2)得到的float值为0.5f,

但按照byte315ToFloat()函数的说明,"01111000"的mantissaBits尾数长度为3, zeroExponent为15,无负数,
而01111按IEEE 754规范,应该理解为1,所以01111000表达的数值应该为1.0×2^0=1,而不是0.5f
非常之tricky。

通过读byte315ToFloat()函数实现,发现"01111000"转换为32位值0,01111110,00000000000000000000000,
该值按IEEE 754规范的确为0.5f, 其中正负位为1位,指数(exponent)位为8位,尾数(mantissa)位为23位。

而在byteToFloat()和byte315ToFloat()的实现中,我们可以常看到作者将尾数位偏移24-mantissa位,
也就是说,他理解的IEEE 754规范中尾数位不是23位而是24位。

以上仅为我的猜测,因为还没有看到byteToFloat()的具体使用环境。

而且通过测试代码,发现byte和float对应关系:
10000,000==2.0f= 1*2^1
10001,000==8.0f=1*2^3
10010,000==32.0f=1*2^5
01111,000 = 0.5f = 1*2^-1
01110,000==0.125f= 1* 2^-3
完全看不出合理的small float的结构,tricky!!!

posted @ 2007-09-12 16:15 鹏飞万里 阅读(576) | 评论 (1) | 编辑 收藏
 
开始爬lucene
因为工作需要,今天开始学习lucene,
因为有可能以后要深入研究full text的搜索,决定暂时不看in action,
采用最愚笨的方法,直接爬代码。凭借以前的门外汉理解一步一步爬吧,
不知道还能衍生出多少知识。
posted @ 2007-09-12 15:42 鹏飞万里 阅读(218) | 评论 (0) | 编辑 收藏
 
swt中非用户线程访问图形控件的方法

swt中,默认只有用户线程被允许访问UI图形控件和一些图形API,其他非用户线程如果直接访问这类资源时,SWTException直接被抛出。
如果真有这种需求,必须使用*.widget.Display类中的两个线程同步方法:syncExec(Runnable)和asyncExec(Runnable)。方法syncExec()和asyncExec()的区别在于前者要在指定的线程执行结束后才返回,而后者则无论指定的线程是否执行都会立即返回到当前线程。

例子:
Display.getCurrent().asyncExec(new Runnable() {
 public void run() {
  butt.setText("Push");
 }
});


以下载自某论坛(sorry,忘记了出处),关于内存释放:

Rule 1: If you created it, you dispose it.
Rule 2: Disposing the parent disposes the children.
(from http://www.eclipse.org/articles/swt-design-2/swt-design-2.html)

当使用构造函数来创建小窗口或图形对象时,使用完时必须用手工来除掉它。
如果没有使用构造函数就获取小窗口或图形对象,则一定不能用手工来除掉它,因为您未分配它。
如果将对小窗口或图形对象的引用传送至另一个对象,则一定要小心,仍在使用它时一定不要除掉它。与在使用图像的插件模式中所描述的规则相似。)
当用户关闭Shell时,将递归地销毁 shell 及其所有子代小窗口。在此情况下,不需要除掉小窗口本身。然而,必须释放与那些小窗口一起分配的所有图形资源。
如果创建图形对象以便在其中一个小窗口的生命周期内使用它,则在除掉小窗口时必须除掉图形对象。这可以通过向小窗口注册销毁侦听器,并在接收到销毁事件时释放图形对象来实现。

这些规则有一个例外。简单的数据对象(例如,矩形和点)不使用操作系统资源。它们没有 dispose() 方法,您也不需要释放它们。如果有疑问,则检查特定类的 javadoc。

 

posted @ 2007-03-20 15:37 鹏飞万里 阅读(776) | 评论 (2) | 编辑 收藏
 
dojo的第二种包加载方式

第一种方式,zkjbeyond的文章中有很详细的说明http://www.blogjava.net/zkjbeyond/archive/2006/05/05/44676.html
简单说,就是利用Ajax读取包的.js文件后,直接使用eval()运行代码。

除此外,dojo还有另一种加载方式,用在调试阶段(例如使用firebug活Venkman调试dojo时都需要用到,不过我没试过使用MSE7或Visual Studio时是否需要使用这种加载方式)。

你在加载包前,将djConfig.debugAtAllCosts设置为true,那么包的加载方式会有所变化,采用第二种方式。例如:

   djConfig.debugAtAllCosts=true;
dojo.require("dojo.widget.TimBar");
dojo.hostenv.writeIncludes();

此时,dojo会使用加载brower_debug.js文件,
brower_debug.js重载了函数dojo.hostenv.loadUri,这儿,不再直接使用eval()运行,而只是把需要的包push到dojo.hostenv.loadedUris数组中。实现代码:

                var text = this.getText(uri, null, true);
var requires = dojo.hostenv.getRequiresAndProvides(text);
eval(requires.join(";"));
dojo.hostenv.loadedUris.push(uri); //push要加载的包到loadedUris数组中
dojo.hostenv.loadedUris[uri] = true;
var delayRequires = dojo.hostenv.getDelayRequiresAndProvides(text);
eval(delayRequires.join(";"));

从代码可以看出,dojo为了保证加载的顺序,使用dojo.hostenv.getRequiresAndProvides函数将提前依赖的包抠出来,用递归提前push到dojo.hostenv.loadedUris中。
而后,在代码最后,我们只要主动使用dojo.hostenv.writeIncludes();函数,就可一次性将被依赖的包利用document.write包含进来。

btw:
当然,这种方法有不少缺陷:
1、使用document.write方式加载包,会有延迟效应,会等待本页面中代码都执行完才执行包中的代码,自己编码时有点绕,影响可读性;
2、从上面代码中看出,dojo会有更多的IO操作,第一dojo已经完整读取了包代码,但是不马上执行,只是用来分析依赖关系;之后,浏览器又要加载一次包代码。
3、包绝对不允许循环引用。当然,从OO角度,不循环引用是好的方式

所以,这种方式只能用在调试期间

posted @ 2006-05-31 10:08 鹏飞万里 阅读(929) | 评论 (0) | 编辑 收藏
 
关于Javascript的内存泄漏问题的整理稿
     摘要: 常规循环引用内存泄漏和Closure内存泄漏 要了解javascript的内存泄漏问题,首先要了解的就是javascript的GC原理。 我记得原来在犀牛书《JavaScript: The Definitive Guide》中看到过,IE使用的GC算法是计数器,因此只碰到循环 引用就会造成memory leakage。后来一直觉得和观察到的现象很不一致,直到看到Eric的文...  阅读全文
posted @ 2006-05-29 13:18 鹏飞万里 阅读(18638) | 评论 (17) | 编辑 收藏
 
IE 6中无比奇怪的问题,如果函数定义的第一句话的注释中有'层"这个字,IE 6显示页面时直接一片空白
今天发现偶的MapEasy的demo中有个bug,查了半天发现了一个在IE 6下特别古怪的问题:

使用IE6,这个页面无法正确显示
http://mapeasy.sourceforge.net/demo/mapapi0.4alpha20060510/demo2_google_amuse.html

而这个可以
http://mapeasy.sourceforge.net/demo/mapapi0.4alpha20060510/demo2_google.html

而这两个页面的唯一区别就是:第一个页面中有一个函数定义的第一行注释中,带上了"层"这个字。
如果去了“层”这个字,则一切ok。

另外,这两个页面的编码均使用utf8

hoho,IE的bug真是多而古怪了,以后函数的第一行,偶再也不敢写注释了..............
posted @ 2006-05-18 14:53 鹏飞万里 阅读(539) | 评论 (0) | 编辑 收藏
 
关于google map api中的球平投影算法接口: GProjection和GMercatorProjection类

偷懒了一个月,今天终于重新修改了mapeasy中的球平算法应用。
以前的mapeasy中使用google map data的例子不能正确使用经纬度,现在终于可以了。

google map api中有个很有用的接口:GProjection,官方对这个接口的解释是:
    This is the interface for map projections. A map projection instance is passed to the constructor of GMapType. This interface is implemented by the class GMercatorProjection, which is used by all predefined map types. You can implement this interface if you want to define map types with different map projections.

    这个接口最大的作用,就是允许你使用自己的球平算法去投影地图,其中的fromPixelToLatLng()和fromPixelToLatLng()非常重要,他们表示了从经纬度和pixel之间的转换算法。
  
   google做了一个默认的实现GMercatorProjection,使用的是麦卡托算法,google map提供的地图数据,就是根据这个算法投影转换而来的。
   如果你需要使用自己的投影地图,记得一定要自己实现GProjection接口。
  
   google使用的麦卡托算法很有意思,它并没有把整个地球都投影出来,只能投影纬度在85度内的地图。也就是说,最北极和最南极的那部分(纬度85以上),在google地图中是找不到的:)
   
    你可以运行一下这句代码:
alert(map.getCurrentMapType().getProjection().fromLatLngToPixel(new GLatLng(85,0),map.getZoom()));
   你会发现,对应的Y坐标就是0了:)

    如果运行:
alert(map.getCurrentMapType().getProjection().fromLatLngToPixel(new GLatLng(90,0),map.getZoom()));
    那么,Y坐标将为负数:)

    如果你只是希望使用google实现好的麦卡托算法,你还可以直接绕过GMap类,直接使用GMercatorProjection类:
    var zoom=17;
    var latLan=new  GLatLng(85,180);
    var gm
=new GMercatorProjection(zoom+1); 
    var x
=gm.fromLatLngToPixel(latLan,zoom).x;
    var y
=gm.fromLatLngToPixel(latLan,zoom).y;

   而后,你就可以把得到的x,y转换成自己应用的坐标系中的坐标。例如,在我的mapeasy中,坐标系范围是x:[-180,180], y:[-90,90],因此我使用如下的代码进行坐标转换:
/**
 * 
@param lat 经度
 * 
@param lan 纬度
 * 
@param zoom 放大比例
  
*/
function GoogleMapLatLan(lat,lan,zoom){
    
this.lat=lat;
    
this.lan=lan;
    
this.zoom=zoom;
}

GoogleMapLatLan.prototype.fromLatLngToMapEasyPoint
=function(){
   var latLan
=new GLatLng(this.lat,this.lan);
     var zoom
=this.zoom;

    var gm
=new GMercatorProjection(zoom+1); 

    
//merX,merY:根据google提供的Mercator算法算出来的Pixel的
    var merX=gm.fromLatLngToPixel(latLan,zoom).x;
    var merY
=gm.fromLatLngToPixel(latLan,zoom).y;

   
//google使用的麦卡托投影法,并没有把整个地球投影出来,只是投影出纬度在85度以内的地球,也就是说,北纬85度的点,就是最北边的点。而最北极和最南极的那部分地图(纬度85以上),在google提供的地图中是找不到的:)
       
//在zome=0时,如果地图的左上角的点对应的纬经度为:(85,-180),右下角对应的纬经度为(-85,180),此时,使用google提供的Mercator算法算出来的对应的坐标系 范围为:x[0,256],y[0,256],

    
//坐标系的放大倍数
    var scale=Math.pow(2,zoom);
    
    var merXMin
=0;
    var merXMax
=256*scale;
     var merYCenter=128*scale;

    
//meX,meY:MapEasyPoint中的x,y
    
//MapEasy默认的坐标系范围为x:[-180,180],y:[-90,90],因此需要进行转换
    var meX=((merX-merXMin)-(merXMax-merXMin)/2)*180/((merXMax-merXMin)/2);
    var meY
=(merYCenter-merY)*90/merYCenter;

    
return new Point(meX,meY);
};

GoogleMapLatLan.prototype.getPoint
=function(){
    
return this.fromLatLngToMapEasyPoint();
}

    这次写这段代码,才发现google中GLatLan类的distanceFrom(other)函数,实现了计算两个经纬坐标间距离(米为单位)的算法,简单试用了一下,还8错。

     忘了交代 了,我参考的google map api的版本是maps2.48.api.js

 btw:
    今天还是偷懒,没有仔细研究GMercatorProjection的实现代码,留给team中有空的伙伴去研究吧。
    这儿有个Mercator不错的说明:http://en.wikipedia.org/wiki/Mercator_projection

   有兴趣的朋友可以来逛逛http://mapeasy.sf.net。项目问题还好多,包括javascript的memory leakage至今也还没去解决。项目组的成员最近都好忙,也不知道有没有朋友有兴趣加入的。

posted @ 2006-05-10 15:14 鹏飞万里 阅读(4829) | 评论 (7) | 编辑 收藏
 
javascript的prototype
最近有些朋友一直问起prototye是什么,偶一直不怎么做javascript开发,只能简单说说自己的理解。

javascript其实不是严格意义的OO语言,至少他没有很好地实现封装和继承,甚至javascript使用的是function式对象。

因此,javascript有一个奇怪的东西就是prototype,javascript中约定了每个对象都可以包含一个prototype对象的引用(属性),
这个prototype对象在运行时是不可见的,也就是说,定义了之后,你无法直接使用prototype对象。

那么,prototype对象有什么用呢?它的作用,就是当你去调用一个对象的函数或属性时,javascript首先会在这个对象的定义中查找,如果找不到,
他就会去找这个对象的prototype对象有没有这个定义,如果还找不到,他又会去找prototype对象的prototype,一直到对象没有prototype定义为止。

是不是和函数继承的目的很象?这就是javascript的原型继承特性。
但是我们也看出了,这种查找方式,效率非常之低,尤其在prototype链很长的情况下。javascript 2.0会对此有所改进。

另外,prototype的定义方式也很奇怪,他必须以一个对象实例(而不是类)的形式,绑定到其他类上。记得吗?prototype是定义时的,同时又是对象。

例子:
    o1 = function(){};
    o2 = function(){};
    o2.prototype = new o1;  

如果嫌直接使用prototype挺麻烦,你可以去下载一个prototype.js来用,这个封装真的挺不错:)

posted @ 2006-04-24 10:23 鹏飞万里 阅读(2527) | 评论 (2) | 编辑 收藏
 
仅列出标题
共3页: 上一页 1 2 3 
 
<2025年8月>
日一二三四五六
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

 导航

  • BlogJava
  • 首页
  • 发新随笔
  • 发新文章
  • 联系
  • 聚合
  • 管理

 统计

  • 随笔: 28
  • 文章: 0
  • 评论: 38
  • 引用: 1

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论

留言簿(4)

  • 给我留言
  • 查看公开留言
  • 查看私人留言

我参与的团队

  • WebGIS开发设计组(0/0)

随笔档案

  • 2008年2月 (4)
  • 2008年1月 (6)
  • 2007年12月 (2)
  • 2007年11月 (2)
  • 2007年9月 (8)
  • 2007年3月 (1)
  • 2006年5月 (4)
  • 2006年4月 (1)

搜索

  •  

最新评论

  • 1. re: 关于Javascript的内存泄漏问题的整理稿
  • 很有帮助!谢谢
  • --selma
  • 2. re: 关于Javascript的内存泄漏问题的整理稿
  • 对象是值传递的,所以第一段代码不可能是js对象和dom对象的循环引用,而是dom自身的循环引用
  • --axiheyhey
  • 3. re: 关于Javascript的内存泄漏问题的整理稿[未登录]
  • 评论内容较长,点击标题查看
  • --鹏飞万里
  • 4. re: 关于Javascript的内存泄漏问题的整理稿
  • 评论内容较长,点击标题查看
  • --goofect
  • 5. re: 关于Javascript的内存泄漏问题的整理稿
  • 评论内容较长,点击标题查看
  • --goofect

阅读排行榜

  • 1. 关于Javascript的内存泄漏问题的整理稿(18638)
  • 2. 关于google map api中的球平投影算法接口: GProjection和GMercatorProjection类(4829)
  • 3. Lucene如何控制segments的数量?(4690)
  • 4. javascript的prototype(2527)
  • 5. Java7 VB2008都开始支持Lambda(Closure)了(2375)

评论排行榜

  • 1. 关于Javascript的内存泄漏问题的整理稿(17)
  • 2. 关于google map api中的球平投影算法接口: GProjection和GMercatorProjection类(7)
  • 3. 备忘: UTF-8的格式(3)
  • 4. Lucene如何控制segments的数量?(3)
  • 5. 复杂度为log(n)的排序堆栈算法(2)

Powered by: 博客园
模板提供:沪江博客
Copyright ©2025 鹏飞万里