怎样避免C#中将小数转换为字符串时出现科学记数法
在C#中如果float、double、decimal类型的值,小数点后的0太多时,C#会用科学记数法来表示小数的值。
例如下面的double类型0.00009,如果我们直接将其用ToString()方法转换为字符串,就会变为科学记数法9E-05
double number = 0.00009;
string defaultNumber = number.ToString(); //9E-05
此外如果float、double、decimal类型的值只有整数位,且整数后面有很多0,C#也会用科学记数法来表示整数的值,例如下面的double类型210000000000000000,如果我们直接将其用ToString()方法转换为字符串,就会变为科学记数法2.1E+17
double number = ;
string defaultNumber = number.ToString(); //2.1E+17
所以我们可以通过显式声明转换后字符串的格式,避免在C#中出现科学记数法:
using System; namespace NetCoreFloat
{
class Program
{
static void Main(string[] args)
{
double number = 0.00009;
string defaultNumber = number.ToString(); //9E-05 string numberFromToString = number.ToString("N5"); //0.00009 string numberFromStringFormat = string.Format("{0:F5}", number); //0.00009 Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
}
虽然上面的代码可以让小数转换为字符串后不是科学记数法,但是很明显我们需要准确地知道小数点后会有多少位小数,才能保证转换后的精度不会丢失。
如果我们将转换格式的精度设置得过小,就会造成精度损失,如下所示:
using System; namespace NetCoreFloat
{
class Program
{
static void Main(string[] args)
{
double number = 0.00009;
string defaultNumber = number.ToString(); //9E-05 string numberFromToString = number.ToString("N3"); //0.000 string numberFromStringFormat = string.Format("{0:F3}", number); //0.000 Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
}
而如果我们将转换格式的精度设置得过大,又会在小数最后产生多余的0,如下所示:
using System; namespace NetCoreFloat
{
class Program
{
static void Main(string[] args)
{
double number = 0.00009;
string defaultNumber = number.ToString(); //9E-05 string numberFromToString = number.ToString("N10"); //0.0000900000 string numberFromStringFormat = string.Format("{0:F10}", number); //0.0000900000 Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
}
对此我们需要在转换格式中使用#字符,#字符不会在小数最后产生多余的0,如下所示:
using System; namespace NetCoreFloat
{
class Program
{
static void Main(string[] args)
{
double number = 0.00009; string numberFromToString = number.ToString("0.#####"); //0.00009
numberFromToString = number.ToString("0.##########"); //0.00009 number = 100.00009;
numberFromToString = number.ToString("0.#####"); //100.00009
numberFromToString = number.ToString("0.##########"); //100.00009 number = ;
numberFromToString = number.ToString("0.#####"); //
numberFromToString = number.ToString("0.##########"); // Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
}
实际上我们可以最大声明339个#字符,这样可以保证所有小数都能被正确地转换为字符串:
using System; namespace NetCoreFloat
{
class Program
{
static void Main(string[] args)
{
double number = 0.00009; string numberFromToString = number.ToString("0." + new string('#', ));//0.00009 Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
}
我们也可以声明一个类FormatStrings,将339个#字符声明为一个字符串常量DoubleFixedPoint,这样用起来也会更方便:
using System; namespace NetCoreFloat
{
public static class FormatStrings
{
public const string DoubleFixedPoint = "0.###################################################################################################################################################################################################################################################################################################################################################";
} class Program
{
static void Main(string[] args)
{
double number = 0.00009; string numberFromToString = number.ToString(FormatStrings.DoubleFixedPoint);//0.00009 Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
}
C#浮点数的精度问题
我们这里就拿double类型来举例,float和decimal类型以此类推, double的最大值是(double.MaxValue):
179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
其中有15位非0数字,也就是前面的179769313486232,那么它表示double类型可以存储整数位加小数位一共15位的有效数字(也就是说double类型中,第1位和最后1位非0的数字,一共能有15位)。
例如如果我们声明一个18位的小数number,然后通过ToString方法将其输出为字符串:
double number = 1234567890.12345678;//整数10位,小数8位
string numberFromToString = number.ToString("0." + new string('#', ));//1234567890.12346
可以看到ToString方法输出的是1234567890.12346,整数位加小数位一共只有15位,其中最后一位小数数字是6,是因为被#字符四舍五入了。
现在我们提高整数位的位数到13位,声明一个一共21位的小数,我们看看结果如何:
double number = 1234567890123.12345678;//整数13位,小数8位
string numberFromToString = number.ToString("0." + new string('#', ));//1234567890123.12
可以看到这次最后ToString方法输出的是1234567890123.12,整数位加小数位还是一共只有15位,而这次由于整数位占用了15位中的13位数字,所以小数位只剩下2位数字。
接下来我们声明一个一共20位的整数给double类型,看看结果如何:
double number = ;//整数20位
string numberFromToString = number.ToString("0." + new string('#', ));//
可以看到这次最后ToString方法输出的是12345678901231200000,原因就是因为double类型最大只能存储15位有效数字,所以最后5位1被截断了变为了0,只剩下了前面15位有效数字。
参考文献:
Converting numbers to strings without scientific notation in C#
Double to string conversion without scientific notation
怎样避免C#中将小数转换为字符串时出现科学记数法的更多相关文章
- C语言中将数字转换为字符串的方法
C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串.以下是用itoa()函数将整数转换为字符串的一个例子: # include <stdio. h># ...
- Postgresql/Greenplum中将数字转换为字符串TO_CHAR函数前面会多出一个空格
-- 问题1..Postgresql中将数字转换为字符串前面多出一个空格. SELECT TO_CHAR(, '); -- 解决1.使用如下,参数二前面加上fm就可以去掉空格了,如下: SELECT ...
- 在java中,怎样把一个double数转换为字符串时,不用科学计数法表示。
解决方法1: 对Double类型的数字进行 格式化输出 ,相对来说不是很精确 import java.text.DecimalFormat; public class TestDouble_Str ...
- Linq to SQL 中将数字转换为字符串
使用LINQ to Entities中的SqlFunctions调用数据库中的函数 添加引用System.Data.Entity 引用命名空间 using System.Data.Objects.Sq ...
- JS中将一个值转换为字符串的3种方法
1.value.toString() 2."" + value 3.String(value) 第一种方法存在的问题是,它不能把null和undefined转换为字符串.还有第二种 ...
- C#数字类型输出字符串时保留指定小数位数的方法
1.使用占位符: 1)float f = 321.12345F;f.ToString("0.00");这样做无论f是不是整数,都将加上2位小数. 2)float f = 321.1 ...
- struts2:JSON在struts中的应用(JSP页面中将对象转换为JSON字符串提交、JSP页面中获取后台Response返回的JSON对象)
JSON主要创建如下两种数据对象: 由JSON格式字符串创建,转换成JavaScript的Object对象: 由JSON格式字符串创建,转换成JavaScript的List或数组链表对象. 更多关于J ...
- error:将字符串转换为 uniqueidentifier 时失败
sql server查询中出现 将字符串转换为 uniqueidentifier 时失败异常 原因为id设置为uniqueidentifier 字段,在where查询时需要做转换cast(id as ...
- 解决sqoop报错:SQLServerException: 将字符串转换为 uniqueidentifier 时失败。
报错栈: Error: java.io.IOException: Cannection handler cannot recover failure: at org.apache.sqoop.mapr ...
随机推荐
- php开发中sql语句拼接示例
1.插入语句 $sql="insert into Ad(AdClassID,AdType,AdTit,AdFileName,AdUrl,AShow,Addtime) values('&quo ...
- ADO.NET访问Access(文本数据库)数据操作(CRUD)
1,ADO.NET访问Access(文本数据库)数据操作(CRUD) 2,DatabaseDesign 文本数据库Northwind.mdb 3,/App_Code 3.1,/App_Code/DBC ...
- django网站搭建常用的一些代码
from functools import wrapsdef check_user_login(func): @wraps(func) def return_wrapper(request, *arg ...
- nginx/iptables动态IP黑白名单实现方案
nginx/iptables动态IP黑白名单实现方案 一.手动封IP步骤 1.Nginx手动封IP 1.获取各个IP访问次数 awk '{print $1}' nginx.access.log |so ...
- Linux学习之十二-Linux文件属性
Linux文件属性 在Linux中,对于每个文件都有相应属性,以Linux中root用户家目录下新建文件a.txt为例,在a.txt中输入几个字符 使用命令ls -ild a.txt查看文件的权限等 ...
- 【温故知新】——BABYLON.js学习之路·前辈经验(二)
前言:在上一篇随笔BABYLON.js学习之路·前辈经验(一)中回顾了组内同事们长时间在Babylon开发实践中的总结出的学习之路和经验,这一篇主要对开发中常见的一些功能点做一个梳理,这里只作为温故知 ...
- linux中脚本扑捉(trap)信号问题
扑捉ctrl+c信号: #!/bin/bash trap ; function trap() { echo "You press Ctrl+C."; echo "Exit ...
- Xcode中的变量模板(variable template)的使用方法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 假设认为写的不好请多提意见,假设认为不错请多多支持点赞.谢谢! hopy ;) 你可能常常会写一些小的代码片段,里面自然少不了一些关键的变量. ...
- 《C专家编程》数组和指针并不同--多维数组
<C专家编程>数组和指针并不同 标签(空格分隔): 程序设计论著笔记 1. 背景理解 1.1 区分定义与声明 p83 声明相当于普通声明:它所说明的并不是自身,而是描写叙述其它地方创建的对 ...
- 宜信开源|微服务任务调度平台SIA-TASK入手实践
引言 最近宜信开源微服务任务调度平台SIA-TASK,SIA-TASK属于分布式的任务调度平台,使用起来简单方便,非常容易入手,部署搭建好SIA-TASK任务调度平台之后,编写TASK后配置JOB进行 ...