コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2022年9月5日 >>> 2022年8月27日
link もっと後

2022年9月5日

C言語の符号付き整数型は2の補数ですか?

目次: C言語とlibc

コンピュータで負の値を表現するときは「2の補数を使います」と習った方は多いと思います。C言語もそうでしょうか?

答えは「いいえ。そして、はい。」です。

従来の整数型

「いいえ。」の方は、整数型intやlongです。これらの型は2の補数とは限りません。sign and magnitudeや、1の補数表現が許されます。符号と値だけでなく、意味のないビット(パディングビット)の存在も許されています。C11 committee draftの6.2.6.2の定義を見ましょう。

N1570 (C11 committee draft) 6.2.6.2の定義
6.2.6.2 Integer types

1 (unsigned系の話なので省略)

2 For signed integer types, the bits of the object representation shall be divided
into three groups: value bits, padding bits, and the sign bit. There need not be any
padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit.
Each bit that is a value bit shall have the same value as the same bit in the object
representation of the corresponding unsigned type (if there are M value bits in the signed
type and N in the unsigned type, then M <= N). If the sign bit is zero, it shall not affect
the resulting value. If the sign bit is one, the value shall be modified in one of the
following ways:

- the corresponding value with sign bit 0 is negated (sign and magnitude);
- the sign bit has the value -(2^M ) (two’s complement);
- the sign bit has the value -(2^M - 1) (ones’ complement).

Which of these applies is implementation-defined, as is whether the value with sign bit 1
and all value bits zero (for the first two), or with sign bit and all value bits 1 (for one's
complement), is a trap representation or a normal value. In the case of sign and
magnitude and ones’ complement, if this representation is a normal value it is called a
negative zero.

この節は何を言っているのかすこぶるわかりにくいので、ざっくり和訳と具体例を載せます。わかりやすくなっていると嬉しいです。間違いがあったら教えていただけると嬉しいです。

N1570 (C11 committee draft) 6.2.6.2の定義(ざっくり和訳)
6.2.6.2 Integer types

1省略

2符号付き整数型の場合、オブジェクト表現のビットは、値ビット、パディングビット、符号ビットの3つのグループに分けなければならない。
パディングビットは持っても持たなくても構わないが、符号付きchar型はパディングビットをもってはならない。符号ビットは1ビットで
なければならない。値ビットの各ビットは、対応する符号なし型のオブジェクト表現と同じビットでなければならない。
(もし符号付き型にMビットの値ビットがあって、符号なし型にNビットの値ビットがあるなら、M <= Nである)

符号ビットが0なら結果の値には影響しない。符号ビットが1なら、値は次のいずれかの方法で修正されなければならない。

- 符号ビットが0の時の値がそのまま負の値(sign and magnitude)
(例)
10000000 -> -0  ←負のゼロ、もしくはトラップ
10000001 -> -1
10000010 -> -2
...
11111101 -> -125
11111110 -> -126
11111111 -> -127

- 符号ビットが -(2^M) の値(2の補数)
(例)
10000000 -> -128
10000001 -> -127
10000010 -> -126
...
11111101 -> -3
11111110 -> -2
11111111 -> -1

- 符号ビットが -(2^M - 1) の値(1の補数)
(例)
10000000 -> -127
10000001 -> -126
10000010 -> -125
...
11111101 -> -2
11111110 -> -1
11111111 -> -0  ←負のゼロ、もしくはトラップ

このうちどれを適用するかは実装依存である。符号ビットが1で値ビットが全て0(sign and magnitudeと2の補数のとき)、
もしくは符号ビットと値ビットが全て1(1の補数のとき)を持つ値が、トラップ表現か正常な表現かについても同様に実装依存である。
sign and magnitudeと1の補数の場合は、この表現を正常な値とするなら、その値は「負のゼロ(negative zero)」と
呼ばれる。

負の値を表現する方法はいくつかあって、今はほぼ全てのアーキテクチャで2の補数が一般的です。しかし古いアーキテクチャではsign and magnitudeや1の補数を採用していたものがあったのかもしれませんね。

正確なビット幅の整数型

「はい。」の方は、C99で登場した新しい整数型(intN_tのような型)です。こちらは2の補数、パディングビットなしという割り切った仕様です。しかし一般的に良く使われているint8_t, int16_t, int32_tが必ず使えるとは限らないことに注意が必要です。

N1570 (C11 committee draft) 7.20.1.1の定義とざっくり和訳
7.20.1.1 Exact-width integer types

1 The typedef name intN_t designates a signed integer type with width N, no padding
bits, and a two's complement representation. Thus, int8_t denotes such a signed
integer type with a width of exactly 8 bits.

2 The typedef name uintN_t designates an unsigned integer type with width N and no
padding bits. Thus, uint24_t denotes such an unsigned integer type with a width of
exactly 24 bits.

3 These types are optional. However, if an implementation provides integer types with
widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a
two's complement representation, it shall define the corresponding typedef names.


(ざっくり和訳)

1型名intN_tは、幅N、パディングビットなし、2の補数表現の符号付き整数型であることを示す。
したがってint8_tは、幅が正確に8ビットの符号付き整数型を示す。

2型名uintN_tは、幅N、パディングビットなし、2の補数表現の符号なし整数型であることを示す。
したがってuint24_tは、幅が正確に24ビットの符号付き整数型を示す。

3これらの型はオプションである。しかし実装が8, 16, 32, 64ビット、パディングビットなし、
2の補数表現(符号付きの場合)を持つ整数型を提供する場合は、対応するtypedef名を定義しなければならない。

現代のアーキテクチャに合わせてsign and magnitudeと1の補数をバッサリ切った雰囲気を感じます。仕様で気になるのは3ですね。optionalで実装依存とおっしゃっています。これは困ります……。

確実を期すならint_least32_t(規格上requiredなので)を使えば良いですが、最低でも32bitという仕様は不便です。本当は何bitです?という処理を書かねばならないでしょう。名前も長くて使いにくいですし。

編集者:すずき(2023/02/04 22:02)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2022年9月4日

Asciidocをさらに活用

前回(2022年9月3日の日記参照)、Asciidocのプレビュー環境の設定方法を紹介(Chrome or VSCode)しました。今回はさらにAsciidocの便利機能とそのプレビューを使えるようにします。

ちなみにこのプレビュー機能はVSCode限定となります。Chromeでも使えると便利なんですけどね……。

asciidoctor-diagramで他のツールと連携

Asciidocにはasciidoctor-diagramというextensionがあり、他のツール向けテキストを *.adoc内に記述すると、ツールと連携して自動的に画像を生成し、自動的に文書内に埋め込む機能があります。

例えばUMLをテキストで記述するPlatUMLと連携する場合は、

asciidoctor-diagramを使ってPlantUMLと連携

= Hello

== World

This is hello world.

[plantuml]
----
@startuml
A -> B : ccc
@enduml
----

このように [plantuml] の後にPlantUML向けのテキストを書きます。プレビューや他形式に変換した場合、PlantUMLのテキストの代わりにPlantUMLが出力した画像が表示されていることがわかると思います。


asciidoctor-diagramを使った出力例

各ツールを起動して画像に変換&リネームしてAsciidocに画像表示の記述を書く方法と比べれば、利便性は天と地の差でしょう。

Rubyのインストール

AsciidoctorやextensionはRubyで実装されているため、Rubyをインストールする必要があります。

Rubyの公式サイト(サイトへのリンク)を見る限り、Windows向けインストールにはRubyInstallerというツール(サイトへのリンク)がおススメのようです。

Rubyの起動確認
c:\app>ruby --version

ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x64-mingw-ucrt]

RubyInstallerはPATHの設定も自動的に行います。インストール後、コマンドプロンプトを起動してrubyを起動できればインストール成功です。

asciidoctor-diagramのインストール

Rubyをインストールしたら、asciidoctor-diagramをインストールします。同時にasciidoctorもインストールされます。

asciidoctor-diagramのインストール
C:\app>gem install asciidoctor-diagram

Fetching asciidoctor-diagram-plantuml-1.2022.5.gem
Fetching asciidoctor-diagram-ditaamini-1.0.3.gem
Fetching asciidoctor-diagram-2.2.3.gem
Fetching asciidoctor-2.0.17.gem
Successfully installed asciidoctor-diagram-plantuml-1.2022.5
Successfully installed asciidoctor-diagram-ditaamini-1.0.3
Successfully installed asciidoctor-2.0.17
Successfully installed asciidoctor-diagram-2.2.3
Parsing documentation for asciidoctor-diagram-plantuml-1.2022.5
Installing ri documentation for asciidoctor-diagram-plantuml-1.2022.5
Parsing documentation for asciidoctor-diagram-ditaamini-1.0.3
Installing ri documentation for asciidoctor-diagram-ditaamini-1.0.3
Parsing documentation for asciidoctor-2.0.17
Installing ri documentation for asciidoctor-2.0.17
Parsing documentation for asciidoctor-diagram-2.2.3
Installing ri documentation for asciidoctor-diagram-2.2.3
Done installing documentation for asciidoctor-diagram-plantuml, asciidoctor-diagram-ditaamini, asciidoctor, asciidoctor-diagram after 4 seconds
4 gems installed

コマンドプロンプトからGemで一発インストール可能で便利です。asciidoctorはRubyのbinディレクトリの配下にスクリプトが配置されるようです。

asciidoctorの起動確認
c:\app>asciidoctor --version

Asciidoctor 2.0.17 [https://asciidoctor.org]
Runtime Environment (ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x64-mingw-ucrt]) (lc:Windows-31J fs:UTF-8 in:UTF-8 ex:UTF-8)

インストール後、コマンドプロンプトからasciidoctorを起動できればインストール成功です。

Javaのインストール

今回はPlantUMLとの連携を試しますので、PlantUMLの環境も整えます。PlantUMLの実行にはJavaが必要です。

PlantUMLを実行するだけならJRE(Java Runtime Environment)で十分ですが、もし今後Java言語での開発を行う予定があれば、OpenJDKをインストールした方が良いです。私はJavaも使うので Oracle OpenJDKのダウンロードサイト からOpenJDKをダウンロードしました。現状の最新版は18.0.2.1でアーカイブのファイル名はopenjdk-18.0.2.1_windows-x64_bin.zipです。

ダウンロードしたzipファイルを展開すると、jdk-18.0.2.1のような名前のディレクトリがあるので適当な場所に移動(= インストールに相当)します。この際にディレクトリ名をリネームしても良いです。

JDKを適当な場所に配置したらPATHを設定します。例えばJDKをc:\app\jdkにインストールしたとすると、


JDKのPATH設定

こんな感じでPATHに追加します。

Javaの起動確認
c:\app>java -version

openjdk version "18.0.2.1" 2022-08-18
OpenJDK Runtime Environment (build 18.0.2.1+1-1)
OpenJDK 64-Bit Server VM (build 18.0.2.1+1-1, mixed mode, sharing)

PATH追加後、コマンドプロンプトからjavaを起動できればインストール成功です。

VSCodeの設定

VSCode側のプレビュー設定も変更する必要があります。

まずはAsciiDocの設定ページを開いてasciidoctor_jsによるプレビュー生成を無効化します。asciidoctor_jsはasciidoctor-diagramに対応していないからです。プレビュー画面がエラー表示になるかもしれませんが、気にしないでください。


asciidoctor_jsによるプレビュー生成を無効化

次にasciidoctorがasciidoctor-diagramを使うように設定します。具体的には起動時のオプションに -r asciidoctor-diagramを追加します。


asciidoctor-diagramを追加

今までの設定がうまくいっているなら、プレビュー画面が更新されてPlantUMLのテキストの代わりにUMLの画像が表示されるはずです。

まとめ

手順として書いてみると思ったより長いですが、asciidoctor-diagramはなかなか便利です。描画ツールでUMLを書いて、画像にしてAsciidocに埋め込んで……みたいなウザい作業とはお別れです。

画像を使わずテキストで記述するので、差分取得も容易です。画像ファイルで往々にして発生する、原稿がどっか行って更新できなくなった、などのトラブルも防いでくれることでしょう。

編集者:すずき(2022/09/03 23:42)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2022年9月3日

MarkDownのその向こう

簡単なドキュメントやメモはMarkDownで書くことが多いですが、気合を入れた文章にはやや不向きで、図表を入れ始めた辺りから表現力不足が辛くなってきます。

MarkDownで強行突破しても良いですが、より表現力がある主にドキュメント向けのマークアップテキスト……となると、太古から続くTeX、最近だとAsciiDoc、reST(reStructured Text)、Sphinx などが覇権を争っているようです。

私は良し悪しを語るほどマークアップテキストに詳しくないですし、特にAsciidocでなければダメってこともなくて、好きなものを使えば良いと思いますが、今回は訳あってAsciidocを使います。

Asciidocのプレビュー環境

マークアップテキストの読み書きは普段お使いのテキストエディタを使えば良いです。しかしプレビューはテキストエディタではできないことが多く、ちょっと困ります。Asciidocのプレビュー環境として、

  • Google ChromeのAsciidoctor.js Live Preview
  • VSCodeのAsciiDoc Extension

私はこの2つを使うことが多いです。下記に設定方法のメモを残しておきます。

Chrome + Asciidoctor.js Live Preview

ChromeウェブストアからAsciidoctorと検索するだけです。


Chrome AsciiDoctor.js Live Preview

あとはオプションの「オン」と「ファイルのURLへのアクセスを許可する」を有効にすると、


AsciiDoctor.jsのオプション

Chromeに *.adocのファイルをドラッグ&ドロップなどして開けば、プレビュー画面が出るはずです。内容を更新すると自動的にプレビューも更新されます。


ChromeのAsciidocプレビュー画面

これでテキストエディタで編集しつつ、Chromeからローカルディスク上のAsciidocがプレビューできます。簡単で良いですね。

VSCode + AsciiDoc拡張機能

VSCodeのExtensionsからasciidocと検索するだけです。


AsciiDoc Extension

フォルダ内の *.adocファイルを開いて、Ctrl+Shift+Vを押すとプレビュー画面が出るはずです。2分割して右側に出せるので便利ですね。


VSCodeのAsciidocプレビュー画面

これでVSCodeからローカルディスク上のAsciidocを編集しながらプレビューできます。これも簡単ですね。

編集者:すずき(2022/09/03 18:43)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2022年8月29日

マンガ紹介

目次: マンガ紹介

久しぶりにお気に入りのマンガ紹介シリーズ。短めの完結作品を2つ。

赤髪の女商人(全3巻)
最近完結しました。転生ものではない、まっとう?な人生逆転劇です。紹介文には「理不尽はあっても救いはない」とあって不安を煽りますが、理性にあふれ話の通じる人ばかりで、イカレポンチや理不尽な行動をするヤカラは出てこないのでご安心ください(蛮族とすら商売を始めるのです)。読んでてイライラもなく、好きな作品です。あとは作品の尺の関係でしょうか……、展開が早くて一介の商人から王家お抱えまで超スピード出世します。爽快で面白いですね。
死んだ息子の遺品に息子の嫁が入っていた話(全2巻)
最初のページ目を見たときは不謹慎系のギャグマンガかな?と思いましたが、全く違いました。主人公はアンドロイドですがSF感はあまりなく、人情、良い話系が広がる良い作品です。終わり方も良かったです。2巻で完結していてちょっと短いかな……もっと読みたいな〜とは思いました。
編集者:すずき(2022/08/30 23:15)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2022年9月5日 >>> 2022年8月27日
link もっと後

管理用メニュー

link 記事を新規作成

<2022>
<<<09>>>
----123
45678910
11121314151617
18192021222324
252627282930-

最近のコメント5件

  • link 21年3月13日
    すずきさん (03/05 15:13)
    「あー、このプログラムがまずいんですね。ご...」
  • link 21年3月13日
    emkさん (03/05 12:44)
    「キャストでvolatileを外してアクセ...」
  • link 24年1月24日
    すずきさん (02/19 18:37)
    「簡単にできる方法はPowerShellの...」
  • link 24年1月24日
    KKKさん (02/19 02:30)
    「追伸です。\nネットで調べたらマイクロソ...」
  • link 24年1月24日
    KKKさん (02/19 02:25)
    「私もエラーで困ってます\n手動での回復パ...」

最近の記事3件

  • link 24年3月25日
    すずき (03/26 03:20)
    「[Might and Magic Book One TASのその後] 目次: Might and Magicファミコン版以前(...」
  • link 21年10月4日
    すずき (03/26 03:14)
    「[Might and Magicファミコン版 - まとめリンク] 目次: Might and Magicファミコン版TASに挑...」
  • link 24年3月19日
    すずき (03/20 02:52)
    「[モジュラージャックの規格] 古くは電話線で、今だとEthernetで良く見かけるモジュラージャックというコネクタとレセプタク...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 03/26 03:20