我正在尝试使用 fmt.Printf() 将一些 float 格式化为相同的宽度。
例如,给定浮点值 0.0606060606060606、0.3333333333333333、0.05、0.4 和 0.1818181818181818,我想将每个值格式化为 10 个 rune :
0.06060606
0.33333333
0.05
0.4
0.18181818
但是我不明白它是怎么做到的。文档说
For floating-point values, width sets the minimum width of the field and precision sets the number of places after the decimal, if appropriate, except that for %g/%G it sets the total number of digits. For example, given 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5. The default precision for %e and %f is 6; for %g it is the smallest number of digits necessary to identify the value uniquely.
因此,如果我使用 %f,则更大的数字将不适合 10 个字符的限制,因此需要 %g。要获得 10 的最小宽度是 %10g 并且要获得最大数量的 9 位数字(+1 为点)它是 %.9g,但是将它们组合在 %10.9g 的行为与我预期的不一样
0.0606060606
0.333333333
0.05
0.4
0.181818182
为什么我得到的字符串是 10 个 rune ,其他字符串是 11 个 rune 和其他字符串是 12 个 rune ?
特别是,%.9g 似乎并没有产生总共 9 位数字。参见示例:http://play.golang.org/p/ie9k8bYC7r
最佳答案
首先,我们需要正确理解文档:
width sets the minimum width of the field and precision sets the number of places after the decimal, if appropriate, except that for %g/%G it sets the total number of digits.
这一行在语法上是正确的,但是这句话最后部分的it真的很令人困惑:它实际上指的是精度,而不是宽度.
因此,让我们看一些例子:
123.45
12312.2
1.6069
0.6069
0.0006069
然后你像 fmt.Printf("%.4g") 一样打印它,它给你
123.5
1.231e+04
1.607
0.6069
0.0006069
只有 4 个数字,不包括所有小数点和指数。但是等等,最后两个例子会发生什么?你开玩笑吧,这不是超过 5 位数吗?
这是打印中令人困惑的部分:前导 0 不会算作数字,并且当少于 4 个零时不会收缩。
让我们使用以下示例查看 0 行为:
package main
import "fmt"
func main() {
fmt.Printf("%.4g\n", 0.12345)
fmt.Printf("%.4g\n", 0.012345)
fmt.Printf("%.4g\n", 0.0012345)
fmt.Printf("%.4g\n", 0.00012345)
fmt.Printf("%.4g\n", 0.000012345)
fmt.Printf("%.4g\n", 0.0000012345)
fmt.Printf("%.4g\n", 0.00000012345)
fmt.Printf("%g\n", 0.12345)
fmt.Printf("%g\n", 0.012345)
fmt.Printf("%g\n", 0.0012345)
fmt.Printf("%g\n", 0.00012345)
fmt.Printf("%g\n", 0.000012345)
fmt.Printf("%g\n", 0.0000012345)
fmt.Printf("%g\n", 0.00000012345)
}
和输出:
0.1235
0.01235
0.001234
0.0001234
1.234e-05
1.234e-06
1.235e-07
0.12345
0.012345
0.0012345
0.00012345
1.2345e-05
1.2345e-06
1.2345e-07
所以你可以看到,当前导 0 少于 4 个时,它们将被计算在内,如果多于 4 个,则收缩。
好的,接下来是宽度。根据文档,width 仅指定最小宽度,包括小数位和指数。这意味着,如果您的位数多于 width 指定的位数,它将超出宽度。
请记住,宽度将被视为最后一步,这意味着它需要首先满足精度字段。
让我们回到您的案例。您指定了 %10.9g,这意味着您希望总位数为 9,不包括前导 0,最小宽度为 10,包括小数位和指数,精度优先。
0.0606060606060606:取 9 位不带前导 0 将得到 0.0606060606,因为它已经是 12 宽度,它超过了最小宽度 10;
0.3333333333333333:取 9 位不带前导 0 将得到 0.333333333,因为它已经是 11 宽度,它超过了最小宽度 10;
0.05:取前导 0 的 9 位数字将得到 0.05,因为它小于宽度 10,它将用另外 6 个宽度填充以获得宽度 10;
0.4:同上;
0.1818181818181818:取前导 0 的 9 位数字将得到 0.181818182 和舍入,因为它已经是 11 宽度,它超过了最小宽度共 10 个。
所以这就解释了为什么你得到了有趣的打印。
关于go - %g 中具有宽度和精度字段的 fmt.Printf 行为异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36464068/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手