ตัดทศนิยมสองตำแหน่งโดยไม่ต้องปัดเศษ


109

สมมติว่าฉันมีค่า 3.4679 และต้องการ 3.46 ฉันจะตัดทศนิยมให้เหลือสองตำแหน่งโดยไม่ต้องปัดเศษได้อย่างไร

ฉันได้ลองทำสิ่งต่อไปนี้แล้ว แต่ทั้งสามให้ 3.47:

void Main()
{
    Console.Write(Math.Round(3.4679, 2,MidpointRounding.ToEven));
    Console.Write(Math.Round(3.4679, 2,MidpointRounding.AwayFromZero));
    Console.Write(Math.Round(3.4679, 2));
}

สิ่งนี้ส่งคืน 3.46 แต่ดูเหมือนว่าจะสกปรกอย่างไร:

void Main()
{
    Console.Write(Math.Round(3.46799999999 -.005 , 2));
}
c#  math  rounding 

คำตอบ:


153
value = Math.Truncate(100 * value) / 100;

ระวังว่าเศษส่วนเหล่านี้ไม่สามารถแทนค่าได้อย่างแม่นยำในจุดลอยตัว


13
ใช้ทศนิยมสำหรับค่าของคุณและคำตอบนี้จะได้ผล ไม่น่าจะใช้ได้กับการแสดงจุดลอยตัวใด ๆ เสมอไป
แห้ง

1
นั่นทำให้ฉันสงสัยว่ามันควรจะเป็นไปได้หรือไม่ที่จะระบุทิศทางการปัดเศษในตัวอักษรทศนิยม อืม.
Steve314

จะต้องมีวิธีการบางอย่างที่จะบอกโปรแกรมเมอร์ว่าการคำนวณโดยใช้สมมติฐานว่าตัวเลขสามารถเก็บตัวเลขได้มากกว่า 308 หลักนั้นไม่เหมาะสมอย่างยิ่ง Double สามารถจัดเก็บได้เพียง 15 Overflow เป็นคุณสมบัติที่มากที่นี่มันล้นมาก
Hans Passant

ฉันขอโทษฉันคิดว่า "ค่า" เป็นทศนิยม
nightcoder

54

จะมีประโยชน์มากกว่าหากมีฟังก์ชันเต็มรูปแบบสำหรับการใช้งานจริงในการตัดทศนิยมใน C # สิ่งนี้สามารถแปลงเป็นวิธีการขยายทศนิยมได้ค่อนข้างง่ายหากคุณต้องการ:

public decimal TruncateDecimal(decimal value, int precision)
{
    decimal step = (decimal)Math.Pow(10, precision);
    decimal tmp = Math.Truncate(step * value);
    return tmp / step;
}

หากคุณต้องการ VB.NET ลองสิ่งนี้:

Function TruncateDecimal(value As Decimal, precision As Integer) As Decimal
    Dim stepper As Decimal = Math.Pow(10, precision)
    Dim tmp As Decimal = Math.Truncate(stepper * value)
    Return tmp / stepper
End Function

จากนั้นใช้มันดังนี้:

decimal result = TruncateDecimal(0.275, 2);

หรือ

Dim result As Decimal = TruncateDecimal(0.275, 2)

1
สิ่งนี้จะล้นออกมาเป็นจำนวนมาก
nightcoder

1
หากต้องการเพิ่มลงใน night coder การที่คุณใช้ Int32 เป็นตัวกลางในฟังก์ชันของคุณจะทำให้เกิดการล้น คุณควรใช้ Int64 หากคุณต้องส่งเป็นจำนวนเต็ม คำถามคือว่าทำไมคุณถึงต้องการที่จะได้รับค่าโสหุ้ยพิเศษนั้นอยู่ดีเนื่องจาก Truncate จะส่งกลับค่าปริพันธ์ทศนิยมอยู่ดี เพียงทำสิ่งที่ชอบ: ขั้นตอนทศนิยม = (ทศนิยม) Math.Pow (10, ความแม่นยำ); ส่งคืน Math.Truncate (ขั้นตอน * ค่า) / ขั้นตอน;
Sarel Esterhuizen

ฉันทิ้งนักแสดงไปที่ Integer ฉันปล่อยให้พวกเขาแยกบรรทัดเพื่อให้อ่านง่ายขึ้นและเข้าใจวิธีการทำงานของฟังก์ชัน
Corgalore

27

ใช้ตัวดำเนินการโมดูลัส:

var fourPlaces = 0.5485M;
var twoPlaces = fourPlaces - (fourPlaces % 0.01M);

ผลลัพธ์: 0.54


1
ฉันไม่เข้าใจ (อ่าน: ไม่ได้ใช้เวลาในการตรวจสอบ) ทุกโซลูชั่นแฟนซีอื่น ๆ เหล่านี้ไม่ว่าสิ่งที่ผมกำลังมองหา ขอบคุณ!
Isaac Baker

เล่นนี้บนสุทธิซอclickyผลิต0.5400... ความคำตอบโดย D. Nesterov0.54ด้านล่างผลิตที่คาดว่าจะ
ttugates

คุณรู้หรือไม่ว่า @ttugates 0.54 และ 0.5400 นั้นมีค่าเท่ากันใช่ไหม? มันไม่สำคัญว่าหลายศูนย์ปฏิบัติตามเว้นแต่ / จนกว่าจะถึงเวลาที่จะรูปแบบการแสดงผลซึ่งในกรณีนี้ผลจะเป็นเหมือนกันถ้ารูปแบบถูกต้อง: $"{0.54m:C}"ผลิต"$0.54"และใช่ ผลิต$"{0.5400m:C}" "$0.54"
Leonard Lewis

26

วิธีสากลและรวดเร็ว (ไม่มีMath.Pow()/ การคูณ) สำหรับSystem.Decimal:

decimal Truncate(decimal d, byte decimals)
{
    decimal r = Math.Round(d, decimals);

    if (d > 0 && r > d)
    {
        return r - new decimal(1, 0, 0, false, decimals);
    }
    else if (d < 0 && r < d)
    {
        return r + new decimal(1, 0, 0, false, decimals);
    }

    return r;
}

4
ฉันทำการทดสอบทั้งหมดที่กล่าวถึงในคำตอบอื่น ๆ และทำงานได้อย่างสมบูรณ์ น่าแปลกใจที่ไม่มีการโหวตเพิ่มขึ้น เป็นที่น่าสังเกตว่าทศนิยมสามารถอยู่ระหว่าง 0 ถึง 28 เท่านั้น (อาจใช้ได้สำหรับคนส่วนใหญ่)
RichardOD

1
ฉันสองที่ นี่คือคำตอบที่ดีที่สุด +1
Branko Dimitrijevic

1
คำตอบที่ดีฉันเรียกว่า "คิดนอกกรอบ"
bruno.almeida

23

ปัญหาหนึ่งของตัวอย่างอื่น ๆ คือพวกเขาคูณค่าอินพุตก่อนหาร มีกรณีขอบที่คุณสามารถล้นทศนิยมได้โดยการคูณครั้งแรกกรณีขอบ แต่สิ่งที่ฉันเจอ ปลอดภัยกว่าที่จะจัดการกับส่วนที่เป็นเศษส่วนแยกกันดังนี้:

    public static decimal TruncateDecimal(this decimal value, int decimalPlaces)
    {
        decimal integralValue = Math.Truncate(value);

        decimal fraction = value - integralValue;

        decimal factor = (decimal)Math.Pow(10, decimalPlaces);

        decimal truncatedFraction = Math.Truncate(fraction * factor) / factor;

        decimal result = integralValue + truncatedFraction;

        return result;
    }

ฉันรู้ว่ามันเก่า แต่ฉันสังเกตเห็นและมีปัญหากับเรื่องนี้ ปัจจัยที่คุณมีอยู่ที่นี่คือ int ดังนั้นหากคุณตัดทอนเป็นทศนิยมจำนวนมาก (พูด 25) จะทำให้ผลลัพธ์สุดท้ายมีข้อผิดพลาดที่แม่นยำ ฉันแก้ไขโดยเปลี่ยนประเภทปัจจัยเป็นทศนิยม
TheKingDave

@TheKingDave: อาจจะไม่เกี่ยวข้อง แต่เนื่องจากปัจจัยไม่สามารถมีทศนิยมได้ควรจะดีกว่าที่จะจำลองให้ยาวใช่ไหม
Ignacio Soler Garcia

@SoMoS สำหรับฉัน Decimal ทำงานได้ดีขึ้นเพราะมันให้ค่าการจัดเก็บข้อมูลสูงสุดสำหรับตัวประกอบ มันยังมีข้อ จำกัด แต่ก็ใหญ่พอสำหรับการสมัครของฉัน ในทางกลับกันไม่สามารถจัดเก็บจำนวนมากพอสำหรับแอปพลิเคชันของฉัน ตัวอย่างเช่นหากคุณทำการ Truncate (25) ด้วยความยาวจะมีความไม่ถูกต้องบางอย่าง
TheKingDave

อัปเดตเพื่อให้สามารถตัดทอนจำนวนสถานที่ได้มากขึ้นตามคำแนะนำของ @TheKingDave ขอบคุณ
Tim Lloyd

6

ฉันจะทิ้งวิธีแก้ปัญหาสำหรับเลขฐานสิบ

คำตอบบางส่วนสำหรับทศนิยมในที่นี้มีแนวโน้มที่จะล้น (ถ้าเราส่งเลขฐานสิบที่มีขนาดใหญ่มากและเมธอดจะพยายามคูณมัน)

โซลูชันของ Tim Lloyd ได้รับการปกป้องจากการล้น แต่ก็ไม่เร็วเกินไป

วิธีแก้ปัญหาต่อไปนี้เร็วกว่าประมาณ 2 เท่าและไม่มีปัญหาล้น:

public static class DecimalExtensions
{
    public static decimal TruncateEx(this decimal value, int decimalPlaces)
    {
        if (decimalPlaces < 0)
            throw new ArgumentException("decimalPlaces must be greater than or equal to 0.");

        var modifier = Convert.ToDecimal(0.5 / Math.Pow(10, decimalPlaces));
        return Math.Round(value >= 0 ? value - modifier : value + modifier, decimalPlaces);
    }
}

[Test]
public void FastDecimalTruncateTest()
{
    Assert.AreEqual(-1.12m, -1.129m. TruncateEx(2));
    Assert.AreEqual(-1.12m, -1.120m. TruncateEx(2));
    Assert.AreEqual(-1.12m, -1.125m. TruncateEx(2));
    Assert.AreEqual(-1.12m, -1.1255m.TruncateEx(2));
    Assert.AreEqual(-1.12m, -1.1254m.TruncateEx(2));
    Assert.AreEqual(0m,      0.0001m.TruncateEx(3));
    Assert.AreEqual(0m,     -0.0001m.TruncateEx(3));
    Assert.AreEqual(0m,     -0.0000m.TruncateEx(3));
    Assert.AreEqual(0m,      0.0000m.TruncateEx(3));
    Assert.AreEqual(1.1m,    1.12m.  TruncateEx(1));
    Assert.AreEqual(1.1m,    1.15m.  TruncateEx(1));
    Assert.AreEqual(1.1m,    1.19m.  TruncateEx(1));
    Assert.AreEqual(1.1m,    1.111m. TruncateEx(1));
    Assert.AreEqual(1.1m,    1.199m. TruncateEx(1));
    Assert.AreEqual(1.2m,    1.2m.   TruncateEx(1));
    Assert.AreEqual(0.1m,    0.14m.  TruncateEx(1));
    Assert.AreEqual(0,      -0.05m.  TruncateEx(1));
    Assert.AreEqual(0,      -0.049m. TruncateEx(1));
    Assert.AreEqual(0,      -0.051m. TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.14m.  TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.15m.  TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.16m.  TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.19m.  TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.199m. TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.101m. TruncateEx(1));
    Assert.AreEqual(0m,     -0.099m. TruncateEx(1));
    Assert.AreEqual(0m,     -0.001m. TruncateEx(1));
    Assert.AreEqual(1m,      1.99m.  TruncateEx(0));
    Assert.AreEqual(1m,      1.01m.  TruncateEx(0));
    Assert.AreEqual(-1m,    -1.99m.  TruncateEx(0));
    Assert.AreEqual(-1m,    -1.01m.  TruncateEx(0));
}

2
ฉันไม่ชอบคำต่อท้าย "Ex" C # รองรับการโอเวอร์โหลดTruncateวิธีการของคุณจะรวมเข้ากับ. net แบบเนทีฟทำให้ผู้ใช้ได้รับประสบการณ์ที่ราบรื่น
Gqqnbig

1
อัลกอริทึมของคุณทำให้ผลลัพธ์บางอย่างไม่ถูกต้อง โหมด MidpointRounding เริ่มต้นคือการปัดเศษของ Banker ซึ่งจะปัดเศษ 0.5 เป็นค่าคู่ที่ใกล้ที่สุด Assert.AreEqual(1.1m, 1.12m.TruncateEx(1));ล้มเหลวเพราะเหตุนี้ หากคุณระบุการปัดเศษ "ปกติ" (AwayFromZero) ในการเรียก Math.Round แล้วAssert.AreEqual(0m, 0m.TruncateEx(1));ล้มเหลว
Jon Senchyna

1
วิธีเดียวที่จะแก้ปัญหานี้คือถ้าคุณใช้MidpointRounding.AwayFromZeroและใช้รหัสเฉพาะเพื่อจัดการกับค่า 0
Jon Senchyna

1
Jon ถูกต้อง: 0m.TruncateEx (0) ให้ผลลัพธ์เป็น -1 เว้นแต่ว่า 0 จะได้รับการจัดการอย่างชัดเจน ในทำนองเดียวกัน -11m.TruncateEx (0) ให้ผลลัพธ์เป็น -10 เว้นแต่จะใช้ MidpointRounding.AwayFromZero ภายใน Math.Round ดูเหมือนว่าจะทำงานได้ดีกับการปรับเปลี่ยนเหล่านั้นแม้ว่า
Ho Ho Ho

1
แม้ว่าจะมีการเปลี่ยนแปลงสำหรับ AwayFromZero และการจัดการอย่างชัดเจนของ 0, -9999999999999999999999999999m.TruncateEx (0) ส่งผลให้ -9999999999999999999999999998 ดังนั้นจึงยังมีข้อผิดพลาดในบางกรณี
Ho Ho Ho

3

นี่เป็นคำถามเก่า แต่ anwsers จำนวนมากทำงานได้ไม่ดีหรือมากเกินไปสำหรับตัวเลขจำนวนมาก ฉันคิดว่าคำตอบของ D.Nesterov เป็นคำตอบที่ดีที่สุด: แข็งแกร่งง่ายและรวดเร็ว ฉันแค่อยากจะเพิ่มสองเซ็นต์ของฉัน ฉันเล่นกับทศนิยมและตรวจสอบซอร์สโค้ดด้วย จากเอกสารตัวสร้างpublic Decimal (int lo, int mid, int hi, bool isNegative, byte scale)

การแทนค่าฐานสองของเลขฐานสิบประกอบด้วยเครื่องหมาย 1 บิตเลขจำนวนเต็ม 96 บิตและตัวคูณมาตราส่วนที่ใช้ในการหารจำนวนเต็มและระบุว่าส่วนใดเป็นเศษทศนิยม สเกลแฟกเตอร์โดยปริยายคือเลข 10 ยกกำลังเป็นเลขชี้กำลังตั้งแต่ 0 ถึง 28

เมื่อรู้สิ่งนี้แนวทางแรกของฉันคือสร้างอีกอันหนึ่งdecimalที่มีมาตราส่วนตรงกับทศนิยมที่ฉันต้องการทิ้งจากนั้นจึงตัดทอนและสุดท้ายสร้างทศนิยมด้วยมาตราส่วนที่ต้องการ

private const int ScaleMask = 0x00FF0000;
    public static Decimal Truncate(decimal target, byte decimalPlaces)
    {
        var bits = Decimal.GetBits(target);
        var scale = (byte)((bits[3] & (ScaleMask)) >> 16);

        if (scale <= decimalPlaces)
            return target;

        var temporalDecimal = new Decimal(bits[0], bits[1], bits[2], target < 0, (byte)(scale - decimalPlaces));
        temporalDecimal = Math.Truncate(temporalDecimal);

        bits = Decimal.GetBits(temporalDecimal);
        return new Decimal(bits[0], bits[1], bits[2], target < 0, decimalPlaces);
    }

วิธีนี้ไม่เร็วไปกว่าของ D. Nesterov และมันซับซ้อนกว่าดังนั้นฉันจึงเล่นให้มากขึ้นอีกหน่อย ฉันเดาว่าต้องสร้างตัวช่วยdecimalและดึงบิตสองครั้งทำให้ช้าลง ในความพยายามครั้งที่สองของฉันฉันจัดการกับส่วนประกอบที่ส่งคืนโดยวิธี Decimal.GetBits (ทศนิยม d) ด้วยตัวเอง แนวคิดคือการแบ่งส่วนประกอบ 10 เท่าหลาย ๆ ครั้งตามต้องการและลดขนาด รหัสจะขึ้น (หนัก) ในDecimal.InternalRoundFromZero (อ้างอิงสิบวัน decimalCount int) วิธีการ

private const Int32 MaxInt32Scale = 9;
private const int ScaleMask = 0x00FF0000;
    private const int SignMask = unchecked((int)0x80000000);
    // Fast access for 10^n where n is 0-9        
    private static UInt32[] Powers10 = new UInt32[] {
        1,
        10,
        100,
        1000,
        10000,
        100000,
        1000000,
        10000000,
        100000000,
        1000000000
    };

    public static Decimal Truncate(decimal target, byte decimalPlaces)
    {
        var bits = Decimal.GetBits(target);
        int lo = bits[0];
        int mid = bits[1];
        int hi = bits[2];
        int flags = bits[3];

        var scale = (byte)((flags & (ScaleMask)) >> 16);
        int scaleDifference = scale - decimalPlaces;
        if (scaleDifference <= 0)
            return target;

        // Divide the value by 10^scaleDifference
        UInt32 lastDivisor;
        do
        {
            Int32 diffChunk = (scaleDifference > MaxInt32Scale) ? MaxInt32Scale : scaleDifference;
            lastDivisor = Powers10[diffChunk];
            InternalDivRemUInt32(ref lo, ref mid, ref hi, lastDivisor);
            scaleDifference -= diffChunk;
        } while (scaleDifference > 0);


        return new Decimal(lo, mid, hi, (flags & SignMask)!=0, decimalPlaces);
    }
    private static UInt32 InternalDivRemUInt32(ref int lo, ref int mid, ref int hi, UInt32 divisor)
    {
        UInt32 remainder = 0;
        UInt64 n;
        if (hi != 0)
        {
            n = ((UInt32)hi);
            hi = (Int32)((UInt32)(n / divisor));
            remainder = (UInt32)(n % divisor);
        }
        if (mid != 0 || remainder != 0)
        {
            n = ((UInt64)remainder << 32) | (UInt32)mid;
            mid = (Int32)((UInt32)(n / divisor));
            remainder = (UInt32)(n % divisor);
        }
        if (lo != 0 || remainder != 0)
        {
            n = ((UInt64)remainder << 32) | (UInt32)lo;
            lo = (Int32)((UInt32)(n / divisor));
            remainder = (UInt32)(n % divisor);
        }
        return remainder;
    }

ฉันไม่ได้ทำการทดสอบประสิทธิภาพอย่างเข้มงวด แต่ใน MacOS Sierra 10.12.6 โปรเซสเซอร์ Intel Core i3 3,06 GHz และการกำหนดเป้าหมาย NetCore 2.1 วิธีนี้ดูเหมือนจะเร็วกว่าของ D.Nesterov มาก (ฉันจะไม่ให้ตัวเลขตั้งแต่ ดังที่ฉันได้กล่าวไปแล้วการทดสอบของฉันไม่เข้มงวด) ขึ้นอยู่กับว่าใครก็ตามที่ใช้สิ่งนี้ในการประเมินว่าประสิทธิภาพที่ได้รับนั้นคุ้มค่าหรือไม่สำหรับความซับซ้อนของโค้ดที่เพิ่มเข้ามา


ฉันต้องโหวตให้คะแนนเพราะความคิดและความพยายามทั้งหมด คุณตั้งค่าของ Nesterov เป็นเกณฑ์มาตรฐานและยังคงเดินหน้าต่อไป
AndrewBenjamin



1

นี่คือวิธีการขยาย:

public static decimal? TruncateDecimalPlaces(this decimal? value, int places)
    {
        if (value == null)
        {
            return null;
        }

        return Math.Floor((decimal)value * (decimal)Math.Pow(10, places)) / (decimal)Math.Pow(10, places);

    } // end

0

หากคุณไม่กังวลมากเกินไปเกี่ยวกับประสิทธิภาพและผลลัพธ์สุดท้ายของคุณอาจเป็นสตริงได้แนวทางต่อไปนี้จะสามารถแก้ไขปัญหาความแม่นยำแบบลอยได้:

string Truncate(double value, int precision)
{
    if (precision < 0)
    {
        throw new ArgumentOutOfRangeException("Precision cannot be less than zero");
    }

    string result = value.ToString();

    int dot = result.IndexOf('.');
    if (dot < 0)
    {
        return result;
    }

    int newLength = dot + precision + 1;

    if (newLength == dot + 1)
    {
        newLength--;
    }

    if (newLength > result.Length)
    {
        newLength = result.Length;
    }

    return result.Substring(0, newLength);
}

6
จริงๆแล้ว hardcoding '.' ไม่ใช่ความคิดที่ดีควรใช้ System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator [0]
David Airapetyan

0

นี่คือการใช้งานฟังก์ชัน TRUNC ของฉัน

private static object Tranc(List<Expression.Expression> p)
{
    var target = (decimal)p[0].Evaluate();

    // check if formula contains only one argument
    var digits = p.Count > 1
        ? (decimal) p[1].Evaluate()
        : 0;

    return Math.Truncate((double)target * Math.Pow(10, (int)digits)) / Math.Pow(10, (int)digits);
}

0

แล้วนี่?

Function TruncateDecimal2(MyValue As Decimal) As Decimal
        Try
            Return Math.Truncate(100 * MyValue) / 100
        Catch ex As Exception
            Return Math.Round(MyValue, 2)
        End Try
End Function

0

นอกเหนือจากวิธีแก้ปัญหาข้างต้นแล้วยังมีอีกวิธีหนึ่งที่เราสามารถบรรลุได้

    decimal val=23.5678m,finalValue;

    //take the decimal part    
     int decimalPos = val.ToString().IndexOf('.');
     string decimalPart = val.ToString().Substring(decimalPosition+1,val.ToString().Length);
    //will result.56
   string wholePart=val.ToString().Substring(0,decimalPos-1);
   //concantinate and parse for decimal.
  string truncatedValue=wholePart+decimalPart;//"23.56"
  bool isDecimal=Decimal.tryParse(truncatedValue,out finalValue);//finalValue=23.56

0

ภายใต้เงื่อนไขบางประการอาจเพียงพอ

ฉันมีค่าทศนิยมของ SubCent = 0.0099999999999999999999999999Mที่มีแนวโน้มที่จะจัดรูปแบบเป็น| SubCent: 0.010000 | ผ่านstring.Format("{0:N6}", SubCent );และตัวเลือกการจัดรูปแบบอื่น ๆ อีกมากมาย

ความต้องการของฉันไม่ได้ปัดเศษค่า SubCent แต่ไม่บันทึกทุกหลักด้วย

สิ่งต่อไปนี้ตรงตามความต้องการของฉัน:

string.Format("SubCent:{0}|", 
    SubCent.ToString("N10", CultureInfo.InvariantCulture).Substring(0, 9));

ซึ่งส่งคืนสตริง: | SubCent: 0.0099999 |

เพื่อรองรับค่าที่มีส่วนจำนวนเต็มสิ่งต่อไปนี้คือจุดเริ่มต้น

tmpValFmt = 567890.0099999933999229999999M.ToString("0.0000000000000000000000000000");
decPt = tmpValFmt.LastIndexOf(".");
if (decPt < 0) decPt = 0;
valFmt4 = string.Format("{0}", tmpValFmt.Substring(0, decPt + 9));

ซึ่งส่งคืนสตริง:

valFmt4 = "567890.00999999"

0

ฉันกำลังใช้ฟังก์ชันนี้เพื่อตัดทอนค่าหลังทศนิยมในตัวแปรสตริง

public static string TruncateFunction(string value)
    {
        if (string.IsNullOrEmpty(value)) return "";
        else
        {
            string[] split = value.Split('.');
            if (split.Length > 0)
            {
                string predecimal = split[0];
                string postdecimal = split[1];
                postdecimal = postdecimal.Length > 6 ? postdecimal.Substring(0, 6) : postdecimal;
                return predecimal + "." + postdecimal;

            }
            else return value;
        }
    }

1
แม้ว่ารหัสนี้อาจตอบคำถามได้ แต่การให้บริบทเพิ่มเติมเกี่ยวกับวิธีการและ / หรือเหตุผลในการแก้ปัญหาจะช่วยเพิ่มมูลค่าในระยะยาวของคำตอบ
Nic3500

0

นี่คือสิ่งที่ฉันทำ:

        c1 = a1 - b1;
        d1 = Math.Ceiling(c1 * 100) / 100;

การลบตัวเลขที่ป้อนสองตัวโดยไม่ต้องปัดเศษทศนิยมขึ้นหรือลง เพราะวิธีแก้ปัญหาอื่น ๆ ไม่ได้ผลสำหรับฉัน ไม่รู้ว่ามันจะใช้ได้กับคนอื่นหรือเปล่าฉันแค่อยากแบ่งปันสิ่งนี้ :) หวังว่ามันจะใช้ได้กับผู้ที่กำลังหาวิธีแก้ปัญหาที่คล้ายกับของฉัน ขอบคุณ

PS: ฉันเป็นมือใหม่ดังนั้นอย่าลังเลที่จะชี้ให้เห็นบางอย่างเกี่ยวกับเรื่องนี้ : D นี่เป็นสิ่งที่ดีถ้าคุณกำลังจัดการกับเงินสาเหตุของเซนต์ใช่มั้ย? มันมีทศนิยม 2 ตำแหน่งเท่านั้นและการปัดเศษจะเป็น no


0
        public static void ReminderDigints(decimal? number, out decimal? Value,  out decimal? Reminder)
        {
            Reminder = null;
            Value = null;
            if (number.HasValue)
            {
                Value = Math.Floor(number.Value);
                Reminder = (number - Math.Truncate(number.Value));
            }
        }



        decimal? number= 50.55m;             
        ReminderDigints(number, out decimal? Value, out decimal? Reminder);

0
public static decimal TruncateDecimalPlaces(this decimal value, int precision)
    {
        try
        {
            step = (decimal)Math.Pow(10, precision);
            decimal tmp = Math.Truncate(step * value);
            return tmp / step;
        }
        catch (OverflowException)
        {
            step = (decimal)Math.Pow(10, -1 * precision);
            return value - (value % step);
        }
    }

-2

ที่จริงคุณต้องการ 3.46 จาก 3.4679 นี่เป็นเพียงการแสดงอักขระเท่านั้นดังนั้นจึงไม่มีอะไรเกี่ยวข้องกับฟังก์ชันคณิตศาสตร์ฟังก์ชันคณิตศาสตร์ไม่ได้มีไว้เพื่อทำงานนี้ เพียงใช้รหัสต่อไปนี้

Dim str1 As String
str1=""
str1 ="3.4679" 
  Dim substring As String = str1.Substring(0, 3)

    ' Write the results to the screen.
    Console.WriteLine("Substring: {0}", substring)

Or 
    Please use the following code.
Public function result(ByVal x1 As Double) As String 
  Dim i as  Int32
  i=0
  Dim y as String
  y = ""
  For Each ch as Char In x1.ToString
    If i>3 then
     Exit For
    Else
    y + y +ch
    End if
    i=i+1
  Next
  return y
End Function

รหัสด้านบนสามารถแก้ไขได้สำหรับตัวเลขใด ๆ ใส่รหัสต่อไปนี้ในเหตุการณ์คลิกปุ่ม

Dim str As String 
str= result(3.4679)
 MsgBox("The number is " & str)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.