Go语言的%d,%p,%v等占位符的使用

Python013

Go语言的%d,%p,%v等占位符的使用,第1张

这些是死知识,把常用的记住,不常用的直接查表就行了

golang 的fmt 包实现了格式化I/O函数,类似于C的 printf 和 scanf。

type Human struct {

Name string

}

var people = Human{Name:"zhangsan"}

golang没有 '%u' 点位符,若整数为无符号类型,默认就会被打印成无符号的。

宽度与精度的控制格式以Unicode码点为单位。宽度为该数值占用区域的最小宽度;精度为小数点之后的位数。

操作数的类型为int时,宽度与精度都可用字符 '*' 表示。

对于 %g/%G 而言,精度为所有数字的总数,例如:123.45,%.4g 会打印123.5,(而 %6.2f 会打印123.45)。

%e 和 %f 的默认精度为6

对大多数的数值类型而言,宽度为输出的最小字符数,如果必要的话会为已格式化的形式填充空格。

而以字符串类型,精度为输出的最大字符数,如果必要的话会直接截断。

使用起来很简单,一般配合fmt.Printf()使用,因为fmt的Printf()是有格式的输出,切忌使用Println(),否则将会以字符串的形式输出。

查看原文: golang fmt格式“占位符”

这不就是无符号右移嘛,当时第一感觉是是为了取绝对值,后来发现并不是,尝试了多次之后,发现情况有点诡异啊,我们使用 chrome 调试工具运行一下 js 中的无符号右移 0 位。

不仅是 null 无符号右移会变成 0 , js 中的其他非数值做此运算都会变成 0 。

接下来我们来看看为什么会这样(事实上不仅仅只是无符号右移是这样)。要理解这个问题需要先明白什么是位运算以及为什么需要位运算,然后搞明白 js 中的位运算有什么特别之处。

敬请期待

(这一部分我是拿 java、go 与 js 做对比的。)

这在 java、go、c 中都是不被允许的

细心的人已经发现,基本类型里并没有浮点型。

事实上在 js 中的 Number 类型是不区分 int、long、float、double 类型的( go 的用户们就呵呵一笑了,来来来,我们的浮点型就能王炸你)。回正题,不区分整型、浮点型那怎么存储呢,为了不丢失精度, js 中的 Number 类型实际上一个基于 IEEE 754 标准的双精度64位浮点数( java 的同学就把它当成 double 看)。看到这我想很多人应该能明白为什么 js 里浮点数也能参与位运算了吧。这也是没有办法,因为对于内存来说整型、浮点型都没有区别了。

这里是有一个问题的,因为当 js 需要进行位运算时,会将操作数通通转成 32 位比特序列(0,1),也就是补码。操作完成之后,再按照 64 位浮点数存储

直接丢弃!!! 曾呐!这么虎?

没错,就是这么暴力,那么问题来了,既然小数部分不参与位运算,那么为什么不能像 java、go 那样直接禁止呢?关于这个问题,我想那就是语言设计者的想法,我就不知道了。但是这其实也带来了一些特别的操作,比如在 js 中双取反是可以做取整操作的。

js 需要进行位运算的时候,对于非数值类型,会首先将操作数转成一个整型(就是0)然后在进行运算。这就解释了为什么 js 中可以允许非数值类型参与运算,其实这是个伪命题,因为实质上是对非数值操作数的整型表达式进行的位运算。

这里需要注意,上面说过了 js 中的整型在内存中都是一个 64 位双精度浮点型,但是 js 进行位运算时,会将操作数转成带符号位的 32 位比特序列(0,1),也就是补码。运算结束后,再按照 64 位存储。那么问题来了,这里肯定会存在精度丢失对吧,这应该不难理解。 js 确实也是这样处理的,超过 32 位的部分直接截断。

所以对一个非数值变量做取反操作,得到的一定是 -1,因为实际上等于对 0 做取反操作。

首尾呼应一下,毕竟就是这个问题使我查资料写了这篇文章。

首先解释一下, >>> 无符号右移原本是 java 里特有的(这里是和 js、go 对比,其他语言我没用过,不能乱说)。 js 中的无符号右移跟 java 几乎一样,除了一点两种语言处理方式完全不一样。

那就是并没有真正发生移位的情况下,符号位会不会被替换成0。 java 中是不会替换的,但是 js 中是会发生替换的。

当操作数是正数的时候,不管有没有真的移位并没有区别,因为正数的符号位是 0。

当操作数是负数时,移动位数大于0,也体现不出区别:

但是当操作数是负数,无符号右移 0 位时,区别就大了:

这是因为 -1 的补码是:

>>>0 实际上并没有发生数位变化,但是 js 却会把符号位替换成 0,

此时原来负数的补码,变为了正数的源码(这就是为什么 js 中 -1>>>0 会变成一个巨大的正整数)。

js 中无符号右移时,不管正数、负数都会首先将符号位替换成 0,然后再进行移位。也就是说,该运算符永远返回正整数。

js 的位运算,为什么会有这么多奇怪的地方呢?我相信很多同学都会有这种想法,特别是 java 的同学们吧。为此我查了 js 的历史。

1995 Sun 公司正式发布 java 语言,当时的网景公司正在为它们的 Navigator 浏览器寻找一种网页脚本(此前的浏览器不具备互动能力)。当他们看到 Sun 公司的宣传后,与 Sun 合作开发全新的脚本语言 javascript 。此前我一直不明白 js 既然不是 java 的脚本,为什么叫这个名字。现在懂了,因为当时新脚本语言的决策中, Sun 公司占了很大一环。

1995年5月 按照公司的要求(一个像 java 但是比 java 简单的脚本语言), Brendan Eich 仅用10天就写出了 javascript

在我们膜拜大神的时候,也要认清一个现实,当时给 Brendan Eich 的时间太短了,所以很多问题并没有很好的解决,而且一边模仿 java、c ,一边还要简化数据类型、内存模型。我觉得这就是为什么 js 的位运算这么奇怪的原因。

js 完全套用了 java 的位运算符。

但是 java 的位运算是针对整数的,对 js 没什么用啊,因为 js 中,所有数字都保存为双精度浮点型。如果使用它们的话, js 不得不将操作数先转为整数,然后再进行运算。

所以很多人不建议在 js 中使用位运算,理由是 js 天生就会进行类型转换,使得效率降低。

宏程序序

大家都在问宏程序~其实说起来宏就是用公式来加工零件的,比如说椭圆,如果没有宏的话,我们要逐点算出曲线上的点,然后慢慢来用直线逼近,如果是个光洁度要求很高的工件的话,那么需要计算很多的点,可是应用了宏后,我们把椭圆公式输入到系统中然后我们给出Z坐标并且每次加10um那么宏就会自动算出X坐标并且进行切削,实际上宏在程序中主要起到的是运算作用..宏一般分为A类宏和B类宏.A类宏是以G65 Hxx P#xx Q#xx R#xx的格式输入的,而B类宏程序则是

以直接的公式和语言输入的和C语言很相似在0i系统中应用比较广.由于现在B类宏程序的大量使

用很多书都进行了介绍这里我就不再重复了,但在一些老系统中,比如法兰克OTD系统中由于它的MDI键盘上没有公式符号,连最简单的等于号都没有,为此如果应用B类宏程序的话就只能在计算机上编好再通过RSN-32接口传输的数控系统中,可是如果我们没有PC机和RSN-32电缆的话怎么办呢,那么只有通过A类宏程序来进行宏程序编制了,下面我介绍一下A类宏的引用

A类宏是用G65 Hxx P#xx Q#xx R#xx或G65 Hxx P#xx Qxx Rxx格式输入的xx的意思就是数值,是以um级的量输入的,比如你输入100那就是0.1MM~~~~~.#xx就是变量号,关于变量号是什么意思再不知道的的话我也就没治了,不过还是教一下吧,变量号就是把数值代入到一个固定的地址中,固定的地址就是变量,一般OTD系统中有#0~~~#100~#149~~~#500~#531关闭电源时变量#100~#149被初始化成“空”,而变量#500~#531保持数据.我们如果说#100=30那么现在#100地址内的数据就是30了,就是这么简单.好现在我来说一下H代码,大家可以看到A类宏的标准格式中#xx和xx都是数值,而G65表示使用A类宏,那么这个H就是要表示各个数值和变量号内的数值或者各个变量号内的数值与其他变量号内的数值之间要进行一个什么运算,可以说你了解了H代码A类宏程序你基本就可以应用了,好,现在说一下H代码的各个含义:

以下都以#100和#101和#102,及数值10和20做为例子,应用的时候别把他们当格式就行,

基本指令:

H01赋值格式:G65H01P#101Q#102:把#102内的数值赋予到#101中

G65H01P#101Q#10:把10赋予到#101中

H02加指令格式G65 H02 P#101 Q#102 R#103,把#102的数值加上#103的数值赋予#101

G65 H02 P#101 Q#102 R10

G65 H02 P#101 Q10 R#103

G65 H02 P#101 Q10 R20

上面4个都是加指令的格式都是把Q后面的数值或变量号内的数值加上R后面的数

值或变量号内的数值然后等于到P后面的变量号中.

H03减指令格式G65 H03 P#101 Q#102 R#103,把#102的数值减去#103的数值赋予#101

G65 H03 P#101 Q#102 R10

G65 H03 P#101 Q10 R#103

G65 H03 P#101 Q20 R10

上面4个都是减指令的格式都是把Q后面的数值或变量号内的数值减去R后面的数

值或变量号内的数值然后等于到P后面的变量号中.

H04乘指令格式G65 H04 P#101 Q#102 R#103,把#102的数值乘上#103的数值赋予#101

G65 H04 P#101 Q#102 R10

G65 H04 P#101 Q10 R#103

G65 H04 P#101 Q20 R10

上面4个都是乘指令的格式都是把Q后面的数值或变量号内的数值乘上R后面的数

值或变量号内的数值然后等于到P后面的变量号中.

H05除指令格式G65 H05P#101 Q#102 R#103,把#102的数值除以#103的数值赋予#101

G65 H05 P#101 Q#102 R10

G65 H05 P#101 Q10 R#103

G65 H05 P#101 Q20 R10

上面4个都是除指令格式都是把Q后面的数值或变量号内的数值除以R后面的数

值或变量号内的数值然后等于到P后面的变量号中.(余数不存,除数如果为0的话会出现112报警)

三角函数指令:

H31 SIN正玄函数指令:格式G65 H31 P#101 Q#102 R#103含义Q后面的#102是三角形的斜边R后面的#103内存的是角度.结果是#101=#102*SIN#103,也就是说可以直接用这个求出三角形的另

一条边长.和以前的指令一样Q和R后面也可以直接写数值.

H32 COS余玄函数指令:格式G65 H32 #101 Q#102 R#103含义Q后面的#102是三角形的斜边

R后面的#103内存的是角度.结果是#101=#102*COS#103,也就是说可以直接用这个求出三角形的

另一条边长.和以前的指令一样Q和R后面也可以直接写数值.

H33和H34本来应该是TAN 和ATAN的可是经过我使用得数并不准确,希望有知道的人能够告诉我是为什么?

开平方根指令:

H21格式G65 H21 P#101 Q#102 意思是把#102内的数值开了平方根然后存到#101中(这个指令是非常重要的如果在车椭圆的时候没有开平方跟的指令是没可能用宏做到的.

无条件转移指令:

H80格式:G65 H80 P10 直接跳到第10程序段

有条件转移指令:

H81 H82 H83 H84 H85 H86 ,分别是等于就转的H81不等于就转的H82小于就转的H83大于就转的H84小于等于就转的H85大于等于就转的H86

格式:G65 H8x P10 Q#101 R#102将#101内的数值和#102内的数值相比较,按上面的H8x的码带入H8x中去,如果条件符合就跳到第10程序段,如果不符合就继续执行下面的程序段.

用 户 宏 程 序

能完成某一功能的一系列指令像子程序那样存入存储器,用一个总指令来它们,使用时只需给出这个总指令就能执行其功能。

l 所存入的这一系列指令——用户宏程序

l 调用宏程序的指令————宏指令

l 特点:使用变量

一. 变量的表示和使用

(一) 变量表示 

#I(I=1,2,3,…)或#[<式子>]

例:#5,#109,#501,#[#1+#2-12]

(二) 变量的使用 

1. 地址字后面指定变量号或公式

格式: <地址字>#I

<地址字>-#I

<地址字>[<式子>]

例:F#103,设#103=15 则为F15

Z-#110,设#110=250 则为Z-250

X[#24+#18*COS[#1]]

2. 变量号可用变量代替

例:#[#30],设#30=3 则为#3

3. 变量不能使用地址O,N,I

例:下述方法下允许

O#1;

I#2 6.00×100.0

N#3 Z200.0;

4. 变量号所对应的变量,对每个地址来说,都有具体数值范围

例:#30=1100时,则M#30是不允许的

5. #0为空变量,没有定义变量值的变量也是空变量

6. 变量值定义:

程序定义时可省略小数点,例:#123=149

MDI键盘输一. 变量的种类

1. 局部变量#1~#33

一个在宏程序中局部使用的变量

例: A宏程序 B宏程序

… …

#10=20 X#10 不表示X20

… …

断电后清空,调用宏程序时代入变量值

2. 公共变量#100~#149,#500~#531

各用户宏程序内公用的变量

例:上例中#10改用#100时,B宏程序中的

X#100表示X20

#100~#149 断电后清空

#500~#531保持型变量(断电后不丢失)

3. 系统变量

固定用途的变量,其值取决于系统的状态

例:#2001值为1号刀补X轴补偿值

#5221值为X轴G54工件原点偏置值

入时必须输入小数点,小数点省略时单位为μm

一. 运算指令

运算式的右边可以是常数、变量、函数、式子

式中#j,#k也可为常量

式子右边为变量号、运算式

1. 定义

#I=#j

2. 算术运算

#I=#j+#k

#I=#j-#k

#I=#j*#k

#I=#j/#k

3. 逻辑运算

#I=#JOK#k

#I=#JXOK#k

#I=#JAND#k

4. 函数

#I=SIN[#j] 正弦

#I=COS[#j] 余弦

#I=TAN[#j] 正切

#I=ATAN[#j] 反正切

#I=SQRT[#j] 平方根

#I=ABS[#j] 绝对值

#I=ROUND[#j] 四舍五入化整

#I=FIX[#j] 下取整

#I=FUP[#j] 上取整

#I=BIN[#j] BCD→BIN(二进制)

#I=BCN[#j] BIN→BCD

1. 说明

1) 角度单位为度

例:90度30分为90.5度

2) ATAN函数后的两个边长要用“1”隔开

例:#1=ATAN[1]/[-1]时,#1为了35.0

3) ROUND用于语句中的地址,按各地址的最小设定单位进行四舍五入

例:设#1=1.2345,#2=2.3456,设定单位1μm

G91 X-#1;X-1.235

X-#2 F300;X-2.346

X[#1+#2];X3.580

未返回原处,应改为

X[ROUND[#1]+ROUND[#2]];

4) 取整后的绝对值比原值大为上取整,反之为下取整

例:设#1=1.2,#2=-1.2时

若#3=FUP[#1]时,则#3=2.0

若#3=FIX[#1]时,则#3=1.0

若#3=FUP[#2]时,则#3=-2.0

若#3=FIX[#2]时,则#3=-1.0

5) 指令函数时,可只写开头2个字母

例:ROUND→RO

FIX→FI

6) 优先级

函数→乘除(*,1,AND)→加减(+,-,OR,XOR)

例:#1=#2+#3*SIN[#4];

7) 括号为中括号,最多5重,园括号用于注释语句

例:#1=SIN[[[#2+#3]*#4+#5]*#6];(3重)

一. 转移与循环指令

1.无条件的转移

格式: GOTO 1;

GOTO #10;

2.条件转移

格式: IF[<条件式>] GOTO n

条件式:

#j EQ#k 表示=

#j NE#k 表示≠

#j GT#k 表示>

#j LT#k 表示<

#j GE#k 表示≥

#j LE#k 表示≤

例: IF[#1 GT 10] GOTO 100;

N100 G00 691 X10;

例:求1到10之和

O9500;

#1=0

#2=1

N1 IF [#2 GT10] GOTO 2

#1=#1+#2;

#2=#2+1;

GOTO 1

N2 M301.循环

格式:WHILE[<条件式>]DO m;(m=1,2,3)

ENDm

说明:1.条件满足时,执行DOm到ENDm,则从DOm的程序段

不满足时,执行DOm到ENDm的程序段

2.省略WHILE语句只有DOm…ENDm,则从DOm到ENDm之间形成死循环

3.嵌套

4.EQ NE时,空和“0”不同

其他条件下,空和“0”相同

例:求1到10之和

O0001;

#1=0;

#2=1;

WHILE [#2LE10] DO1;

#1=#1+#2;

#2=#2+#1;

END1;

M30; 这是简单的抛物线程序! G99

S800M3

T0101

G0 X30. .Z10.

#1=0

N10 #2=SQRT[2*#1]

G1X[2*#2]Z-#1F0.05

#1=#1+0.1

IF [#1 LE 50] GOTO 10

G0X30

Z100

M5

M30