美祺's profileEden of HexagonPhotosBlogListsMore ![]() | Help |
|
July 29 Hibernate 对视图的操作及配置也是这几天,在弄Hibernate的时候,发现对于视图的mapping往往做的很不够,如果这个视图里没有主键的话,那是无法搜出要的数据类的。呵呵,这个也就是平时说得给hibernate配视图:)不过,后面的myeclipse3.2平台上已经统一解决了这类问题,通过id类。这个针对的是过去eclipse3.1的平台而言,同时也让自己明白了hibernate的一些小脾气:) hibernate对视图的操作 // Fields // Property accessors public void setId(AllTablePbId id) { public class AllTablePbId implements java.io.Serializable { // Fields private String owner; private String tableName; private String columnName; private String dataType; private String pbcCnam; private String pbcCmnt; // Property accessors public String getOwner() { public void setOwner(String owner) { public String getTableName() { public void setTableName(String tableName) { public String getColumnName() { public void setColumnName(String columnName) { public String getDataType() { public void setDataType(String dataType) { public String getPbcCnam() { public void setPbcCnam(String pbcCnam) { public String getPbcCmnt() { public void setPbcCmnt(String pbcCmnt) { } 配置文件: 通过这样对视图的操作,同样也可以用到对于那些没有定义主键的表,操作方法是一样的。 Java中Double的高精度问题及bigdecimal解决方式 最近有空写了点老的J2EE的代码,发现有一个十分有意思的问题,当用Hibernate从数据库里把浮点数读取出来的时候做一些比如累加的工作,例如 summary 或者递减之类的,就会发现在最后的结果中会出现些许问题。
如:3.41+5.2+56.2+23.3+... (这类两位小数的价钱),结果会出现103.00000000000001这种结果,但是人算的话反而会得出正常的数据。看样子double,float这类数据精度上来了还会有这类问题。
于是,翻了点资料,在有的编程语言中提供了专门的货币类型来处理这种情况,但是Java没有。
四舍五入
我们的第一个反应是做四舍五入。Math类中的round方法不能设置保留几位小数,我们只能
象这样(保留两位): public double round(double value){
return Math.round(value*100)/100.0;
}
非常不幸,上面的代码并不能正常工作,给这个方法传入4.015它将返回4.01而不是4.02,
如我们在上面看到的 4.015*100=401.49999999999994
因此如果我们要做到精确的四舍五入,不能利用简单类型做任何运算
java.text.DecimalFormat也不能解决这个问题:
System.out.println(new java.text.DecimalFormat("0.00").format(4.025));
输出是4.02
BigDecimal 在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者 是工程计算,在商业计算中我们要用 java.math.BigDecimal。BigDecimal一共有4个够造方 法,我们不关心用BigInteger来够造的那两个,那么还有两个,它们是: BigDecimal(double val)
Translates a double into a BigDecimal.
BigDecimal(String val)
Translates the String repre sentation of a BigDecimal into a
BigDecimal. 上面的API简要描述相当的明确,而且通常情况下,上面的那一个使用起来要方便一些。我
们可能想都不想就用上了,会有什么问题呢?等到出了问题的时候,才发现上面哪个够造方 法的详细说明中有这么一段: Note: the results of this constructor can be somewhat unpredictable. One might
assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding. The (String) constructor, on the other hand, is perfectly predictable: new
BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one. 原来我们如果需要精确计算,非要用String来够造BigDecimal不可!在《Effective Java》
一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,这也许是一个 小小的失误吧。 解决方案
现在我们已经可以解决这个问题了,原则是使用BigDecimal并且一定要用String来够造。
但是想像一下吧,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造
成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果( BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?下面我们提供一个工具类 Arith来简化操作。它提供以下静态方法,包括加减乘除和四舍五入: public static double add(double v1,double v2)
public static double sub(double v1,double v2)
public static double mul(double v1,double v2)
public static double div(double v1,double v2)
public static double div(double v1,double v2,int scale)
public static double round(double v,int scale)
附录
源文件Arith.java:
package com.common.util;
import java.math.BigDecimal; /** * 由于Java的简单类型不能够精确的对浮点数进行运算, * 这个工具类提供精确的浮点数运算,包括加减乘除和四舍五入。 */ public final class Arith { // 默认除法运算精度 private static final int DEF_DIV_SCALE = 2; // 这个类不能实例化 private Arith() { } /** * 提供精确的加法运算。 * * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static double sub(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static double mul(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 提供(相对)精确的除法运算,当发生除不尽的情况时, * 精确到小数点以后10位,以后的数字四舍五入。 * * @param v1 被除数 * @param v2 除数 * @return 两个参数的商 */ public static double div(double v1, double v2) { return div(v1, v2, DEF_DIV_SCALE); } /** * 提供(相对)精确的除法运算。 * 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。 * * @param v1 被除数 * @param v2 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static double div(double v1, double v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理。 * * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } } 呵呵,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。这个才是解决的方式,我也试过了发现确实不错。不过话又说回来了,在.net里似乎没有发现有这类问题呀,能说他好么?我看未必,有时候封装的太好,功能太多,往往让人忘记了这些背后本来的面目:) July 27 他们是这样一群男人(转载) 他们是这样一群男人:没有钱,没有像样的球衣,找不到像样的训练场,甚至面临着各种威胁;但他们热爱自己的国家,在足球场上,他们誓死捍卫自己的尊严,拼尽全力,用胜利为苦难中的人民带去一丝快乐。
他们有这样一句名言:“国内每天都有人战死,但从来没有人在足球场上为国家增添耻辱,就算死,也要有尊严地死!”
伊拉克人视这群足球场上的战士为偶像,每当胜利降临,他们宁愿冒着生命的危险,也要走上街头,用枪炮来庆祝足球的胜利。对伊拉克人来说,快乐是一种奢侈,足球为他们带来这种奢侈,他们甘愿为之承受痛苦。
快乐是奢侈
对生活在战火和废墟中的伊拉克人民来说,快乐是一种奢侈。他们要面对别国球迷无法想像的生活困境,如缺水、缺电、缺燃料,恐怖威胁,人身安全无法保证等等。当他们得到快乐时,就像是得到了上天的恩赐。
25日,当伊拉克男足历史性地闯入亚洲杯决赛,首都巴格达瞬间淹没在一片激烈的枪声中,冲锋枪和重机枪的枪声大作。这不是交火,而是疯狂的庆祝,伊拉克人用向天空鸣枪的方式来欢庆胜利。从伊拉克北部库德尔自治区到南部地区,欢庆的球迷随处可见,他们又唱又跳。
整个伊拉克都沉浸在欢乐之中。对于灾难深重的伊拉克人来说,这快乐虽然短暂,却能给受伤的心带来些许慰藉。
伊拉克主帅维埃拉说:“带给伊拉克人民快乐,是送给他们的最好礼物。”
踢球是激情
在伊拉克,球员是靠自己的激情在踢球。
战火烧毁了伊拉克的一切体育设施,连足协的办公大楼都付之一炬,球员们没有足球、没有球衣、没有袜子、没有训练场……什么都没有。
伊拉克球员大多在西亚国家的联赛和本国的联赛效力,像尤尼斯这样能够在卡塔尔加拉法比较专业和规范的足球俱乐部发展的极少,且国家队在国内集训时总是面临难找合适训练场地和备战时间仓促等问题,通常只有去伊拉克北部山区找一个相对安全、但条件相当简陋的地方训练。
人民体育场还被美军占领着,俱乐部和球队都没有钱,球员在战争结束后没有领过一分钱的工资,他们都在靠自己的爱国激情踢球。
就像所有伊拉克人一样,伊拉克球员也面临着各种危险:炸弹、流血、贫困、饥饿、绑架……因扑出韩国队点球而成为伊拉克英雄的门将阿巴斯在赛后就说:“目前在伊拉克踢球还是不安全的,即使伊拉克队夺得亚洲杯冠军,情况也不会改观。”
长期以来,这些威胁一直存在。就在一个月前,在巴格达西边高速公路边的一个水沟里发现了13具尸体,他们都是伊拉克跆拳道运动员。今年二月,两名伊拉克球员在一次爆炸袭击中,一人身亡,一人断腿。去年,伊拉克国奥队球员加尼姆·库代耶尔遭遇了绑架,就连伊拉克奥委会主席也难逃此劫。
然而,在如此恶劣的生存环境和集训条件下,伊拉克球员却一直在坚持,并屡创历史:2000年,伊拉克U19国青队获亚青赛亚军;2004年,伊拉克勇夺雅典奥运会铜牌;现在,他们又破天荒地闯入亚洲杯决赛。
足球是未来
伊拉克足球的胜利对伊拉克人来说还有一种重要的意义,他们把家园的重建精神寄托在伊拉克足球的重建之上。
伊拉克足协主席侯赛因说:“在伊拉克,当足球比赛成为一件正常的事时,就意味着我们的生活已经回归了正常。”
而此次伊拉克闯进亚洲杯决赛,将会引起全世界更多人的关注和帮助。 从地狱里出来的人,比别人更能体会生命的美好;一群死都不怕的人,足球场上还会怕啥。
伊拉克球员身上,勃发着的是最原始的生命张力,像《红高粱》里的汉子,他们的激情不是像火,本身就是一团火。
July 21 FTP协议——相关参数最近弄了一点FTP的client端操作例程,由于在老的平台.net1.1上进行开发,只好使用最基本的socket通信去和Ftp服务通信,因此不得不调用这些FTP的命令,同时参照返回code码。可喜的是,.net2.0后的FLC里给FTP的操作专门提供了一系列方便的类和接口,呵呵,ftpclient好像是这个,省去了好多麻烦呢:) 不过socket的协议接触下也不是什么坏事,至少还知道了通信这个层面的操作规范,算是有所小小收获吧。
FTP命令命令 描述
July 08 Breakdown----Mariah Carey After God made the people, as while he'd like to be the company with them. However human kinds eventually build up hand-in-hand relations with Dog, which's ironically literal joke.
Life's like a chocalate, u'd never know what taste the next time. "I'm trying to be nonchalant about it, u know, Jewel"
<Breakdown> by Mariah Carey
( lyrics from lyric4u.com)
WB: Break, breakdown. Steady breakin' me on down. Break, breakdown. Steady breakin' me on down. (MC: Oooooh) Break, breakdown. Steady breakin' me on down. Break, breakdown. Steady breakin' me on down. MC: You call yesterday to basically say That you care for me but that you're just not in love Immediately I pretended to beel similary And led you to believe I was O.K. To just walk away from the thing That's unyielding and sacred to me Well I guess I'm trying to be nonchalant about it And I'm going the extremes to prove I'm fine without you But in reality I'm slowly loosing my my mind Underneath the guise of a smile gradually I'm dying inside Friends ask me how I feel and I lie convincingly 'Cause I don't want to reveal that fact that I'm suffering So I wear my disguise 'til I go home at night And turn down all the lights and then break down and cry So what do you do when somebody you're devoted to Suddenly just stops loving you and it seems they haven't got a clue Of the pain that rejection is putting you through Do you cling to your pride and sing "I will survive" (KB: Gotta get control and roll, roll, roll on.) Do you lash out and say: "How dare you leave this way" Do you hold on in vain as they just slip away Well I guess I'm trying to be nonchalant about it And I'm going the extremes to prove I'm fine without you But in reality I'm slowly loosing my my mind Underneath the guise of a smile gradually I'm dying inside Friends ask me how I feel and I lie convincingly 'Cause I don't want to reveal that fact that I'm suffering So I wear my disguise 'til I go home at night And turn down all the lights and then break down and cry WB: Yeah, c'mon, yeah, c'mon c'mon. MC: Breakdown, breakdown. WB: Break, breakdown. Steady breakin' me on down. KB: Gotta get control and roll, roll, roll on. WB: Gonna break ya down, only if ya let it. Everyday crazy situations rockin' my mind tryin' to break me down, but I won't let it. Forget it, forget KB: I be feelin' like you're breakin' me down, kickin' me 'round, stressin' me out. I think I better go and get out and let me release some stress. WB: Don't ever wanna feel no pain, pain. Hopin' for the sun, but it looks like rain, rain, rain, rain. Lord, I just wanna maintain. KB: Yeah, I can feel the pressures, y'all, but nevertheless Krayzie won't fall. It's over. It's endin' here. Well I guess I'm trying to be nonchalant about it (WB: Break, breakdown. Steady breakin' me on down) And I'm going the extremes to prove I'm fine without you But in reality I'm slowly loosing my my mind Underneath the guise of a smile gradually I'm dying inside Friends ask me how I feel and I lie convincingly 'Cause I don't want to reveal that fact that I'm suffering So I wear my disguise 'til I go home at night And turn down all the lights and then break down and cry July 07 有趣的两道汇编题——Don't U Break Me down Today 最近有位朋友正好要考到一些和汇编有关的题,所以打来这里要个解决方案。呵呵,我也是一下子来了兴趣,毕竟过去对汇编还是沉迷了一段时间,而且也在上机调ASM的时候成功的把一台PC搞歇了——乱调系统地址造成的(事后知道他们给拿去重装了)。Ok,题目也很简单,就两道,我写的时候加了比较多的注释,大概也是职业使然吧:)
1。从strin单元开始有一串字符,,以* 为结束标志,要求字符串的长度,存入count单元,要求段说明和必要的伪指令。
解答如下:
name length_of_string
data segment ;数据段定义
string db 'dontubreakmedowntoday',2ah ;读取的字符串,2ah是*的ascii码且跟在string后 count db ? ;定义count star equ 2ah ;定义star为*,方便后面比较 data ends stack segment para stack'stack' ;堆栈段的定义(不是很重要,死记)
db 100 dup(?) stack ends code segment ;代码段定义
assume cs:code,ds:data,es:data,ss:stack ;定义各个段的用处 start: proc far begin: push ds mov ax,0 push ax mov ax,data mov ds,ax mov es,ax ;以上的是一个固定的初始化模式,照背就可以了 lea di,string ;设置string串的地址指针 mov dl,0 ;设置串的长度初始长度为0 mov al,star ;设置串的结束标记到al中 again: scasb ;搜索串(逐字节地) je done ;找到结束标记,然后跳转到停止段 inc dl ;计数器加1 jmp again ;循环 done: lea bx,count ;把count的地址入bx寄存器 mov [bx],dl ;把dl的赋给count ret start endp code ends end begin ;game1 over 2。从键盘上输入一行字符,要求第一个为space,否则end,如果是space,则开始接受键入字符,并保存在首地址为buffer的缓冲区,直到接受第二个space为止。(调用中断)
解答如下:
name input_string_store
data segment ;数据段定义 buffer db 100 dup(?) ;预存的缓冲区(100个大小,超过机器肯定崩) space equ 20h ;定义空格,方便比较 data ends stack segment para stack'stack' ;堆栈段的定义(不是很重要,死记)
db 100 dup(?) stack ends code segment ;代码段定义 assume cs:code,ds:data,es:data,ss:stack ;定义各个段的用处 start: proc far begin: push ds mov ax,0 push ax mov ax,data mov ds,ax mov es,ax ;以上的是一个固定的初始化模式,照背就可以了 mov ah,1 ;将ah置1 ;8086汇编中断21H系统功能调用全部子功能 ;AH-01 键盘输入并回显 AL=输入字符 int 21h ;调用中断,这两步是读取输入的步骤 mov bl,al ;al中读取的字符放入bl中 and bl,space ;比较bl和space字符 ;如果相同,则进位标志C清0 jc done ;如果不同C=1,则跳转到结束, ;即第一个输入不是space,结束 ;第一个输入是space,则继续 ;特别注意jc是根据c=1跳转的 lea cx,buffer ;将buffer的首地址入cx寄存器 again: mov ah,1 int 21h ;调用中断,获得输入的字符 mov bl,al ;al中读取的字符放入bl中 and bl,space ;比较bl和space字符 ;如果相同,则进位标志C清0 ;如果不同C=1 jnc done ;当第二次输入space时C=0跳转到结束 ;否则继续 ;特别注意jnc是根据c=0跳转的 mov [cx],bl ;将bl中的字符入cx当前指针 ;指向的地址(即缓冲区) inc cx ;cx的地址自增,指向buffer的下一个存放位置 jmp again ;循环 done: ret start endp code ends end begin ;game2 over |
|
|