none
小数点以下と分離して計算をしたい RRS feed

  • 質問

  • お世話になっております。

    Visual Studio2008にて開発を行っています。

    現在、エクセルシートに値を書き出すプログラムを書いていまして、
    途中ロジックにて、詰まってしまったので質問させてください。

    年月を出すにあたって、小数点以下に12をかけたいのですが、どのような方法が好ましいでしょうか?

    例:値が14.87の場合 0.87部分に12をかける。10.44 小数点以下は丸め込み、結果、14.10 という値へ導きたいです。

    MOD関数を使う際、14.87 mod 1 をやれば、小数点以下のみを抽出出来るのですが、この時点で丸め込みが発生するため、
    0.87=0.9になってしまい、この後算出した値を丸め込む際に、切り捨てるか繰り上げるかで差が出てしまいます。

    よろしくお願いします。

    2011年4月26日 8:08

回答

  • Azlean様 外池様 申し訳ありません。前提のデータについての記述が明確ではなくお手間をかけさせております。
    今回求めるべき値は、年月なのですが、あくまでも表記として「年.月(00.00)」とするものでした。
    そして、そもそもの値の抽出結果が、年単位での抽出だったため、小数点以下、0.01~0.99を 月換算にするため、
    12をかける必要がありました。 その際、0.115以上のもの関しては、0.12となり、表記上、小数点以下は、月として扱っているため、
    12カ月を1年とする処理が必要でした。

    '12カ月の場合は1年にする

    If month >= 0.115 Then
    month = 1.0
    xlBox = Int(year) + month
    Else
    xlBox = Int(year) + month
    End If

    今回はこのように調整しました。アドバイスを下さった方ありがとうございます。
    また、こちらの情報提示力の不足、お許しください。 駆け出しですが、これからも精進いたします。
    • 回答としてマーク y_usiro 2011年4月27日 3:32
    2011年4月27日 3:04

すべての返信

  • 外池と申します。

    Visual Studioで開発をなさっているとのことですが、具体的には言語はなんでしょうか? 一方で、.Net Frameworkを使うことができるのであれば、言語によらず時間(年月日時分秒・・・)を表すデータ型が用意されており、この型には年や月の情報を個別に取り出すロジックが既に組み込まれていますので便利ですので、ご利用をお薦めします。

    一般論として、浮動小数点数の小数点部分だけを取り出す操作において、取り出し操作そのものから丸め処理を完全に排除することは難しいですが、一応、次のような操作でやれます。

    小数点数をfとします。整数部をaとします。小数部をbとします。

    a=切捨てで整数部を取り出す関数(f)
    b=f-a

    となります。切捨てで整数部を取り出す関数は、.Net FrameworkのMathクラスであれば、Floor関数になります。Visual Basicの場合はこれを使うことになろうかと思います。C#ですと、整数型へキャストするだけで同じ効果が得られます。


    (ホームページを再開しました)
    2011年4月26日 8:46
  • 正の数なら Math.Floor を、負の数なら Math.Ceiling を使うと整数部分が抜き出せます。(要は切り捨てです。)
    あとは、元の数から整数を引いてしまえば小数部分だけを取り出せるはずです。

    参考:
      数値の切り捨て/切り上げを行うには?[C#、VB] - @IT
      http://www.atmarkit.co.jp/fdotnet/dotnettips/703mathfloorceiling/mathfloorceiling.html


    具体的な式を組み立てる楽しみは残しておきます。
    2011年4月26日 8:47
  • ほかにも、Math.Truncateなんかもあったりします。
    ここら辺の使い分けが、DOBONさんのサイトに分かりやすく書いてありましたので紹介しておきます。
    [DOBON.NET]
    http://dobon.net/vb/dotnet/programing/round.html
    2011年4月26日 9:13
  • ここはVisual Basicのフォーラムですよん
    2011年4月26日 9:17
  • レスを下さった方々ありがとうございます。
    すみません、VB前提でお話をしてしまいました。使用言語はVBです。

    なるほど、Mathクラスがあるのですね。特に.NET Frameworkは今回使用していませんでしたが、検討してみます。

    現在、以下のように処理をしたのですが、0.96以上が出た場合、0.12に丸め込むため、12カ月=1年という概念が出てしまい、
    さてどうしようか、という感じです。これはIF文を使って解消出来るのでしょうか?
    一度Stringにし、0.12(変数)="1.00" と言った感じの処理になるのでしょうか。
    結構強引にやった感じがあるのですが、最終的に出力した値が数値である必要はないので、この方法でもありなのかな?とは思っています。
    何分まだプログラミングにおける善し悪しを把握しきれてないので、何かアドバイス等あれば引き続きよろしくお願いします。

    -----------------------------------------------------------------------------------------------------
            Dim year As Decimal     '年
            Dim premonth As Decimal '仮月
            Dim month As Decimal    '月

            Dim xlBox As Decimal
            Dim xlBox2 As Decimal
            Dim xlBox3 As Decimal  

          For iRow = inStartRow To inEndRow
                For i = 0 To UBound(Cols)
                    If xlSheet.Cells(iRow, iCol).Value = 0 OrElse CStr(xlSheet.Cells(iRow, iCol).Value) = "" Then
                    ElseIf xlSheet.Cells(iRow, iCol).Value = 100.0 Then

                    Else
                        premonth = xlSheet.Cells(iRow, iCol).Value Mod 1
                        month = (premonth * 12) / 100

                        year = xlSheet.Cells(iRow, iCol).Value / 1

                        xlBox3 = Int(year) + month

                        xlSheet.Cells(iRow, iCol).Value = xlBox3

                    End If
                    iCol = iCol + 2
                Next
                iCol = 3
            Next
            xlRange = xlSheet.Range("A" & inStartRow & ":T" & inEndRow)
    -----------------------------------------------------------------------------------------------------

    2011年4月26日 9:51
  • 現在、以下のように処理をしたのですが、0.96以上が出た場合、0.12に丸め込むため、12カ月=1年という概念が出てしまい、
    さてどうしようか、という感じです。これはIF文を使って解消出来るのでしょうか?

    この部分がよくわかりませんでした。
    実際得られた結果と期待する結果を具体的にわかりやすく記載してください。
    そして、どの部分がわからないかも明示してください。

    month が 0.1152 ではなく、0.12 となるのですか?
    それとも、0.12 に丸め込んだ後、年を示す整数部を加算しなければならないとかそういったことですか?


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2011年4月26日 14:03
    モデレータ
  • 外池です。そうでした、VBのフォーラムでしたね。(どのフォーラムに居るのか失念というか、VSのフォーラムだと勘違いしていました。)

    さて・・・、y_usiroさんが取り組んでおられるプログラミングの前提条件がよくわかりません。逆に、以下、質問させください。回答頂ければ、他の方もレスしやすくなると思います。

    1)最初に受け取るデータはどのように時間を表現したものなのでしょうか? 1年=1.0の浮動小数点ですか?

    2)小数点以下の数値を取り出したとして、小数点以下の数値を月数に変換したい様子ですが、1年=均等な12ヶ月と仮定してしまってよいのでしょうか? (実際の月の長さは、大の月、小の月、2月、と違いますからね?)

    3)月数だって、2.5ヵ月とか、2.4ヵ月とかいう半端な数字(小数点数)になるわけですが、最終的には整数で月数を数えようとされているようにお見受けします。月数を整数で数える際には、どのように丸めたいのですか? 切捨て? 切り上げ? 四捨五入等?

    プログラムそのものを書き下すのもですが、データを処理する前提条件を整理しないと、ご質問とレスが噛み合わないと思います。


    (ホームページを再開しました)
    2011年4月27日 0:23
  • Azlean様 外池様 申し訳ありません。前提のデータについての記述が明確ではなくお手間をかけさせております。
    今回求めるべき値は、年月なのですが、あくまでも表記として「年.月(00.00)」とするものでした。
    そして、そもそもの値の抽出結果が、年単位での抽出だったため、小数点以下、0.01~0.99を 月換算にするため、
    12をかける必要がありました。 その際、0.115以上のもの関しては、0.12となり、表記上、小数点以下は、月として扱っているため、
    12カ月を1年とする処理が必要でした。

    '12カ月の場合は1年にする

    If month >= 0.115 Then
    month = 1.0
    xlBox = Int(year) + month
    Else
    xlBox = Int(year) + month
    End If

    今回はこのように調整しました。アドバイスを下さった方ありがとうございます。
    また、こちらの情報提示力の不足、お許しください。 駆け出しですが、これからも精進いたします。
    • 回答としてマーク y_usiro 2011年4月27日 3:32
    2011年4月27日 3:04
  • 外池です。解決された・・・、ということでよろしいんでしょうか?

    私からお尋ねした件のうち、1)はYesなんでしょうね・・・。2)も暗黙のうちにYesのようですね。

    3)については・・・、y_usiroさんがきちんと整理されているのかどうか、不安ではありますが、まぁ、良いでしょう。ただ、老婆心ながら、シツコイですが、計算結果をどのように使うかをよく確認されたほうがよいかと思います。

    3年と1週間を、3年と表現するのか。3年と1ヶ月と表現するのか。「納期」のような所要期間を安全側に見積もるためのデータだったら「切り上げ」すべきだと思うのですが。(3年を少しでも超えれば、3年と1ヶ月と表示する・・・。)


    (ホームページを再開しました)
    2011年4月27日 3:39
  • 外池様

    はい、現状出力する上での問題点は解決したと判断させていただきました。

    解決した旨のみお伝えし、肝心の頂いた返信へのご対応を失念してしまいました。
    1) 2)ともにYESです 今回データを出すにあたって参照するデータは年を対象としていて、
    例えばデータは「43.74」などになっています。(43年と0.74年=約9カ月
    その際、3)の、月数を求める際に、0.74に対し12をかけた値=8.88をどう見るか、ということなのですが、
    小数点以下は、今回は四捨五入することになっていました。 その上で、9と出力されたこの数値を、
    年と合わせて「00.00」という表記での出力(のちに計算などに使う予定はないため、文字列でも可)が求められていました。
    そこで、もとある数値に対し、どのようなアプローチが必要なのかを模索していたのですが、00.00に対し、
    月の部分を小数点に落とし込むために、9÷100=0.09とし、表示上の解決を計りました。
    そして、「00.12」という表示においては、12カ月を1年とするための処理に対し、単純に00.12=1.00とすることにしました。

    ここまでで、3年と1週間などについてなのですが、1週間と仮定したデータは恐らく、0.0025となるので、当初の
    月数を算出する際の四捨五入時点で、0.00となるため、1カ月とする、
    という前提条件は四捨五入時点で自動的に内包する形となっていました。

    例の納期としてのデータなど、そのデータに付随する意味合いからどういった処理が必要か、は今後の参考にさせていただきます。
    今回は四捨五入での対処を求められていたため、この点は大丈夫だと思います。

    プログラムを始めて約半年ですが、質問ばかり多く恐縮です。
    いずれ自分もアドバイスが出来る側に立てればと思います。 返信ありがとうございました。

    2011年4月27日 4:28