[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [已解决]批处理如何对含科学计数数字的txt批量修改?

我有如下内容的大量txt文件
2.0000000000000001e-001
0.0000000000000000e+000
0.0000000000000000e+000
-2.0000000000000001e-001
1.6695009999999998e+005
2.8049900000000001e+004
需要对科学计数改为正常数字,即如下
0.2
0
0
-0.2
166950.09999999998
28049.900000000001

[ 本帖最后由 alexwxcong 于 2010-5-2 20:30 编辑 ]
1

评分人数

    • Batcher: 感谢主动给标题标注[已解决]字样PB + 2

诚请高手帮忙,俺琢磨了一天了,实在水平太低

TOP

不懂数学,哈哈,不懂科学计数!~不过应该不难,只是麻烦点

TOP

e-001就是前面的2.0000000000000001乘以0.1
e+000数字不变
e+005就是前面的1.6695009999999998乘以100000
e+004就是前面的2.8049900000000001乘以10000

TOP

关键是P难以处理小数

TOP

1,“大量txt文件”是否指多个txt文本?
2,“含科学计数数字”,那么文本中是否还含有其他内容?
如果有,区分规则是什么?
3,“含科学计数数字”的构成规则是什么?
-2.0000000000000001e-001都是这样的模式?
寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

我的漏洞好多,编辑掉。看看我师傅的代码先

[ 本帖最后由 sgaizxt001 于 2010-5-2 04:26 编辑 ]
努力学习,努力挣分

TOP

  1、小数点后的位数是否只保留有16位?
  2、是否所有的正数都没有前缀+而只有负数才有前缀-?
  4、e后的004、005之类的是否有可能会达到999?请给出它的范围。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

1,代码没有优化,所以速度。。。100行转换实测耗时2.46妙,汗一个先
2,要求所有文本内只存在科学记数的内容,不含其他内容。
3,批处理放在同一目录下,新生成的文本将放到test子目录中。
4,e后的数字允许范围为000到999
5,小数部分最多保留16位(按楼主的要求)
6,数字小于0.0000000000000001时将被近似为0.0000000000000001
  1. @echo off&setlocal enabledelayedexpansion
  2. if not exist "test\" md test
  3. for %%z in (*.txt) do (
  4. for /f "usebackq tokens=1,2* delims=e." %%a in ("%%z") do (
  5. set a=%%a&set b=%%b&set c=%%c
  6. set d=!c:~1!
  7. for %%d in (0 0) do if !d:~0^,1!==0 set d=!d:~1!
  8. if !a:~0^,1!==- set n=-&set a=!a:~1!
  9. if !a:~0^,1!==0 (echo.0) else (
  10. set m=!a!!b!
  11. if !c:~0^,1!==+ (
  12. if !d! lss 16 (
  13. set/a d+=1
  14. for %%d in (!d!) do set m=!m:~0,%%d!.!m:~%%d!
  15. ) else (
  16. set/a a=d-16
  17. for /l %%d in (1,1,!a!) do set z=!z!0
  18. set m=!m!!z!
  19. )
  20. ) else (
  21. set/a a=d-1
  22. for /l %%d in (1,1,!a!) do set z=!z!0
  23. set m=0.!z!!m!&set m=!m:~0,18!
  24. )
  25. echo.!m!|find ".">nul 2>nul&&call:f !m!
  26. echo.!n!!m!
  27. )
  28. set n=&set z=))>test\%%z
  29. exit
  30. :f
  31. set f=%1
  32. if %f%==0.0000000000000000 set f=0.0000000000000001
  33. for /f "tokens=1,2 delims=." %%a in ("%f%") do set a=%%a&set b=.%%b
  34. :g
  35. if not "!b:~%g%,1!"=="" set/a g+=1&goto:g
  36. for /l %%a in (1,1,%g%) do if not !b:~-%%a^,1!==0 (
  37. set/a h=%%a-1
  38. if not !h!==0 for %%b in (!h!) do set "b=!b:~0,-%%b!"
  39. goto:e)
  40. :e
  41. set m=%a%%b%&set g=
  42. if %m:~-1%==. set m=%m:~0,-1%
复制代码

[ 本帖最后由 hanyeguxing 于 2010-5-2 03:37 编辑 ]
寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

  大致的思路应当是这样的:
  把数值的正负号、整数部分、分数部分、指数部分和指数的正负号分别保存为变量,然后,把指定长度的纯0字符串拼接起来,拼接的规律为:若指数符号为负,则把纯0字符串放到整数部分之前;若指数符号为正,则把纯0字符串放到小数部分之后。把纯0字符串拼接之后,再根据指数部分把小数点位置做相应的移动,最后,把所有部分拼接起来,去掉整数部分之前和小数部分之后的纯0字符串即可。

  虽然思路比较简单,但是我居然发现在for语句中使用如下代码的时候出错了,如果把其中截取字符串的负号去掉,则该语句正常,百思不得其解:
  1. set num=!str_int:~0,-%num_point%!.!str_int:~%num_point%!!dec!
复制代码
  9楼的代码之所以慢,是因为使用了管道符号,频繁的I/O操作势必会拖慢速度。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

1,本批处理使用%%~fd扩展删除0,所以批处理所在路径中最好别用敏感字符
2,本批处理直接修改原文件,所以运行前推荐先将所有原文件备份分:
  1. @echo off
  2. for %%z in (*.txt) do (
  3.       (for /f "usebackq tokens=1,2* delims=e." %%a in ("%%z") do (
  4.             setlocal enabledelayedexpansion
  5.             set a=%%a&set b=%%b&set c=%%c&set d=!c:~1!
  6.             for %%d in (0 0) do if !d:~0^,1!==0 set d=!d:~1!
  7.             if !a:~0^,1!==- set n=-&set a=!a:~1!
  8.             if !a:~0^,1!==0 (echo.0) else (
  9.             set m=!a!!b!
  10.             if !c:~0^,1!==+ (
  11.             if !d! lss 16 (set/a d+=1&for %%d in (!d!) do set m=!m:~0,%%d!.!m:~%%d!) else (
  12.             set/a a=d-16&for /l %%d in (1,1,!a!) do set z=!z!0
  13.             set m=!m!!z!
  14.             )
  15.             ) else (
  16.             set/a a=d-1&for /l %%d in (1,1,!a!) do set z=!z!0
  17.             set m=0.!z!!m!&set m=!m:~0,18!
  18.             if !m!==0.0000000000000000 set m=0.0000000000000001
  19.             )
  20.             if not "!m:.=!"=="!m!" set "m=!m:0= !"&for /f "delims=" %%d in ("!m!") do set m=%%~fd&set "m=!m:%cd%\=!"&set "m=!m: =0!"
  21.             echo.!n!!m!)
  22.       endlocal))>"%%z_"
  23.       del /q "%%z"
  24.       ren "%%z_" "%%z"
  25. )
复制代码
至于:
原帖由 namejm 于 2010-5-2 03:35 发表
虽然思路比较简单,但是我居然发现在for语句中使用如下代码的时候出错了,如果把其中截取字符串的负号去掉,则该语句正常,百思不得其解:
代码:set num=!str_int:~0,-%num_point%!.!str_int:~%num_point%!!dec!

因为没有看到完整代码,个人猜测是这个原因:http://bbs.bathome.net/thread-7629-4-1.html的46楼

[ 本帖最后由 hanyeguxing 于 2010-5-2 09:02 编辑 ]
寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

谢谢hanyeguxing ,我先备份一个试过了,按你的方法好像是可以,谢谢啊

TOP

原帖由 namejm 于 2010-5-2 01:54 发表
  1、小数点后的位数是否只保留有16位?
  2、是否所有的正数都没有前缀+而只有负数才有前缀-?
  4、e后的004、005之类的是否有可能会达到999?请给出它的范围。



1,小数点后的位数可以不用太多,8位就够了
2,前缀可以不用考虑,可以直接删除E前的那个数字
3,E后面的004/005这种不会超过010

TOP

004/005 是否根据+-确定小数点前移或后移4位或5位?如是这样可否移动这个点呢

TOP

恩,其实科学计数就是移动小数点

TOP

返回列表