[過去ログ] Perlについての質問箱 64箱目 (1002レス)
1-

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
99: 2019/09/14(土)23:58 ID:SgsUVSB1(1) AAS
Perl6使ってる香具師さんいますか?
100: 2019/09/15(日)00:02 ID:epz106Yo(1) AAS
bashで凝ったことを書くことを考えたら、Perlのほうがはるかに簡単。
bashは所詮シェルなので、クォートとかエスケープとか変数とか関数とか、いちいちワナが多いからな。
101
(1): 2019/09/15(日)17:56 ID:riyG3w3b(1) AAS
Perlの利点?
他の言語と同様になんでもできることかな。モジュール色々使うと作るの楽だしOSの違いもかなり吸収されてWindowsでもLinuxでも何も変更せずに動くプログラムも作れる。

シェルスクリプトも外部コマンド動かせば何でもできるとは言えるが、起動のオーバーヘッドの問題や起動しているコマンドの仕様が変わったときに個別に対応しなければいけないなど面倒な事がある。
102
(2): 2019/10/23(水)15:22 ID:Q75cL8J3(1) AAS
>>101
> OSの違いもかなり吸収されてWindowsでもLinuxでも何も変更せずに動くプログラムも作れる。
これでとんでもない目に遭ったぞ。
perlの\nは、内部的にはLF のみだが、OSがWindowsなら、出力する際に
CR+LF に自動的に変換してくれる。
しかし、出力文字コードがutf16le だと、特殊な宣言文を書かない限り、
LF (0x000a)は 「0x000a000d」ではなく、「0x000a0d」に変換され、
ぐちゃぐちゃに文字化けする。

文字化けの原因を特定し、回避方法を見つけるために、ずいぶん時間を取られた。
103: 2019/10/23(水)15:31 ID:7+59i/z7(1) AAS
chcp 1200でいけそうな気がするんだけど
104: 2019/10/23(水)17:37 ID:azQS8Nqn(1) AAS
>>102
\n は他の言語でも気を付けた方が良い。
例えC言語だったとしても歴史的な事情でライブラリが勝手に変換するかも知れない。
この頃はそれにまつわるバグは減ってるとは思うけどね。

ま、少なくとも \n を \x0a だと信じ込んで使うのは止めた方がいいだろうな。
\x0a はあくまでも \x0a と書いた方が良い。
Javaとかでは改行は System.out.println() を使って改行させるようにして \n を埋め込んでの改行は極力避けた方が良い。
105
(1): 2019/10/24(木)00:15 ID:dNYiTPCj(1) AAS
>>102
いや、特殊な宣言文ってなんだよ。PerlIO の man 読めよ。
open 関数や binmode 関数の説明にも「PerlIO を読め」って書いてあるよ。
106
(1): 2019/10/24(木)00:54 ID:NQorbS3o(1) AAS
s/\n//g;
s/\r//g;
俺は常にこうしてる
107: 2019/10/24(木)06:24 ID:rCe9ez9s(1/2) AAS
\nを埋め込んだ箇所が一つでもあったらアウト
みたいな作り方は絶対失敗する
108: 2019/10/24(木)08:28 ID:wmDm31X8(1) AAS
>>106
s/\R//g;
じゃないのか?
109: 2019/10/24(木)09:04 ID:LjTGtkP8(1) AAS
>>105
> いや、特殊な宣言文ってなんだよ。PerlIO の man 読めよ。

結論としては、下のように書けばいいのだが、これはネットで色々探して
見つけてきたもので、PerlIO の man 読んで自分で見い出すことは、
私にはできなかった。それが出来る人は凄いと思う。

binmode STDOUT => ":raw:encoding(utf16le):crlf";
110: 2019/10/24(木)22:37 ID:rCe9ez9s(2/2) AAS
右から読むんだよ
111
(5): 2019/11/06(水)01:45 ID:yvB3xxPc(1/5) AAS
消費税計算(10%)しようとしました。税込550円を消費税と本体価格にする。

$a = 550;
$b = 1.1;

$c = $a / $b;
$d = $a - $c;

$e = int($c);
$f = int ($d);

print すると、
$c は 500
$d は 50.000000000001(0の数はだいたい)

$e は 499
$d は 50

とうやら550 / 1.1 が内部的に割り切れていない様子(おそらく実際は内部的に499.99999999999999になってるのでintすると499に)

ロジックの変更で回避したけど、このバグ聞いたことありますか?
112
(1): 2019/11/06(水)02:54 ID:normnvJW(1/2) AAS
>>111
バグじゃなくて仕様やろ。
Perlの数値型はdoubleなので、1.1が正確に表現できてないんちゃう?
浮動小数点数の誤差についてぐぐれ。
113
(1): 2019/11/06(水)03:29 ID:normnvJW(2/2) AAS
>>111
おせっかいかもだがもうひとつ。
その手の誤差を回避するのは、ロジックでなんとかできることもあるが、実際にはなかなか難しいはず。
たまたま誤差が見えなくなってるだけの可能性もありそうなので、動作確認は慎重にな。

ちゃんとやるなら、decimal的なモジュールを使ったほうが。
あるかどうかは知らんけど。
114
(1): 2019/11/06(水)03:46 ID:QwLiS9cf(1) AAS
>>111
バクではなく仕様。
ちなみにPython,Tclで確認してみましたが同じ出力結果になりました。

どんな言語でも金額の計算や小数点の桁を調整をする場合、
int(切り捨て)、round(四捨五入)、ceil(切り上げ)などで処理するか、
出力時に、printfやsprintfを使って、"%.0f"などを指定して桁を合わせる
必要があると思います。
115: 2019/11/06(水)03:51 ID:ZoqI13Ph(1) AAS
あるよ
use bigrat;
my %ISO_number = (
100 => 0,
125 => 1/3,
160 => 2/3,
200 => 1,
250 => 4/3,
320 => 5/3,
400 => 2,
500 => 7/3,
640 => 8/3,
800 => 3,
1000 => 10/3,
1250 => 11/3,
1600 => 4,
2000 => 13/3,
2500 => 14/3,
3200 => 5,
4000 => 16/3,
5000 => 17/3,
6400 => 6,
8000 => 19/3,
10000 => 20/3,
12800 => 7,
);

# dirty hack: 0/1 force rational type
# warning: if it locate last, sum goes WRONG!
printf "%s\n", 0/1 + $shutter_speed{$ss} + $F_number{$F} - $ISO_number{$ISO};
116: 2019/11/06(水)09:06 ID:dfSHCt1W(1) AAS
浮動小数点の問題は知っていたが、こうなる事は初めて知った。危ないもんだな。

$c = $a / $b; # $c = 500
$e = int($c); # $e = 499
117
(1): 2019/11/06(水)09:28 ID:i85ttsqs(1/4) AAS
>>111
それはバグではないし、昔々からある超有名な仕様。知らないのはお前だけ。
118: 2019/11/06(水)10:08 ID:yvB3xxPc(2/5) AAS
>>112
>>113
>>114
>>117
仕様で他の言語でもあるのですね。Perlで明示的な型指定とかはほぼ考えたことが無かった(1.08の時は意図した結果が得られていた)ので、勉強してみます。
ありがとうございます。
119: 2019/11/06(水)10:29 ID:i85ttsqs(2/4) AAS
言語というよりはライブラリやCPUの問題だ。
しかしだいたいのメジャーな言語が採用しちゃってるので言語に関係なく出ると思って良い。
120
(1): 2019/11/06(水)17:59 ID:j94j+HrP(1) AAS
言語仕様っていうと違和感あるね
意図してこうしてますって感じで
IEEE 754の仕様といえばそうなのかもしれんがあれは規格であって
仕様とはまたニュアンスが違う なんつーか実数扱うときはそんなもんという感覚
121
(1): 2019/11/06(水)18:58 ID:yvB3xxPc(3/5) AAS
>>111
一応、取った対応策です(消費税計算なので精度は不要)
除算解は有効桁数以下が切り捨てになり表示などで見える値以下になると想定しました

$a = 550;
$b = 1.1;

$c = ;
$tax= int($a - $a / $b); # $tax = 50
$net = $a - $tax; # $net = 500

端数を残したまま税込から除算解を引いてintして税とし、税込から税を引いて本体としました
とりあえず期待した結果は得られています

ありがとうございました。
122: 2019/11/06(水)18:59 ID:yvB3xxPc(4/5) AAS
$c = ;

この行余計でした
123
(1): 2019/11/06(水)19:44 ID:mEOqpT9o(1/2) AAS
>>120
C/C++なら規格が精密なのでそういう違和感もわかるが、Perlの場合は逆におかしいやろ。w
124
(2): 2019/11/06(水)19:52 ID:mEOqpT9o(2/2) AAS
>>121
税率によってはきっとアカン場合がありそう。。。
単純な切り捨てはヤバいような。
まあ、そこまでの精度はイランのやろけども。

ちなみに、今回のケースなら、$x/1.1とするのではなく、$x*100/110としたほうが安定しそう?
125
(1): 2019/11/06(水)20:39 ID:yvB3xxPc(5/5) AAS
>>124
うちは税込ものを分離する時は消費税側で小数点以下切り捨てなのでOKなのです
四捨五入とか会計方針によっては稀に問題が出るかもしれませんね
126
(1): 2019/11/06(水)21:15 ID:i85ttsqs(3/4) AAS
1.1を掛けるなら11を掛けてから10で割った方が良いかもな。そうすると正数計算でやれる。
切り上げや四捨五入をしたい場合は10で割る前に一桁目を見て10を足したり足さなかったりすれば良い。
127: 2019/11/06(水)21:18 ID:i85ttsqs(4/4) AAS
ああ。逆か。税込みから本体と税を求めるのか。でも考え方は同じだな。
128
(2): 2019/11/07(木)00:06 ID:gr4VkOsJ(1/2) AAS
>>125
違うぞ。今回の問題点をちゃんとわかってるか?
1.1と書いたリテラルが、実際の値は1.10...となっていて、1.1よりも大きかったことだぞ。

誤差の具合によっては、正確には切り捨てが不要な値でも、除数が大きいせいで計算結果が実際よりも小さい値になってしまって、してはいけない切り捨てが発生してしまう可能性はないんかね。
1-
あと 874 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ

ぬこの手 ぬこTOP 0.018s