Example #1
0
        private void WriteFraction(double value, StringBuilder result,
                                   double fractional, StringBuilder output, SortedList <CellNumberStringMod, object> mods)
        {
            // Figure out if we are to suppress either the integer or fractional part.
            // With # the suppressed part is Removed; with ? it is Replaced with spaces.
            if (!improperFraction)
            {
                // If fractional part is zero, and numerator doesn't have '0', write out
                // only the integer part and strip the rest.
                if (fractional == 0 && !HasChar('0', numeratorSpecials))
                {
                    Writeint(result, output, integerSpecials, mods, false);

                    Special start = lastSpecial(integerSpecials);
                    Special end   = lastSpecial(denominatorSpecials);
                    if (HasChar('?', integerSpecials, numeratorSpecials, denominatorSpecials))
                    {
                        //if any format has '?', then replace the fraction with spaces
                        mods.Add(ReplaceMod(start, false, end, true, ' '), null);
                    }
                    else
                    {
                        // otherwise, remove the fraction
                        mods.Add(deleteMod(start, false, end, true), null);
                    }

                    // That's all, just return
                    return;
                }
                else
                {
                    // New we check to see if we should remove the integer part
                    bool numNoZero   = !HasChar('0', numeratorSpecials);
                    bool intNoZero   = !HasChar('0', integerSpecials);
                    bool intOnlyHash = integerSpecials.Count == 0 || (integerSpecials.Count == 1 && HasChar('#', integerSpecials));

                    bool removeBecauseZero     = fractional == 0 && (intOnlyHash || numNoZero);
                    bool removeBecauseFraction = fractional != 0 && intNoZero;

                    if (value == 0 && (removeBecauseZero || removeBecauseFraction))
                    {
                        Special             start          = lastSpecial(integerSpecials);
                        bool                hasPlaceHolder = HasChar('?', integerSpecials, numeratorSpecials);
                        CellNumberStringMod sm             = hasPlaceHolder
                            ? ReplaceMod(start, true, numerator, false, ' ')
                            : deleteMod(start, true, numerator, false);
                        mods.Add(sm, null);
                    }
                    else
                    {
                        // Not removing the integer part -- print it out
                        Writeint(result, output, integerSpecials, mods, false);
                    }
                }
            }

            // Calculate and print the actual fraction (improper or otherwise)
            try
            {
                int n;
                int d;
                // the "fractional % 1" captures integer values in improper fractions
                if (fractional == 0 || (improperFraction && fractional % 1 == 0))
                {
                    // 0 as a fraction is reported by excel as 0/1
                    n = (int)Math.Round(fractional);
                    d = 1;
                }
                else
                {
                    SimpleFraction frac = SimpleFraction.BuildFractionMaxDenominator(fractional, maxDenominator);
                    n = frac.Numerator;
                    d = frac.Denominator;
                }
                if (improperFraction)
                {
                    n += (int)Math.Round(value * d);
                }
                WriteSingleint(numeratorFmt, n, output, numeratorSpecials, mods);
                WriteSingleint(denominatorFmt, d, output, denominatorSpecials, mods);
            }
            catch (Exception ignored)
            {
                //ignored.PrintStackTrace();
                System.Console.WriteLine(ignored.StackTrace);
            }
        }
Example #2
0
        /** {@inheritDoc} */
        public override void FormatValue(StringBuilder toAppendTo, Object valueObject)
        {
            double value = ((double)valueObject);

            value *= scale;

            // For negative numbers:
            // - If the cell format has a negative number format, this method
            // is called with a positive value and the number format has
            // the negative formatting required, e.g. minus sign or brackets.
            // - If the cell format does not have a negative number format,
            // this method is called with a negative value and the number is
            // formatted with a minus sign at the start.
            bool negative = value < 0;

            if (negative)
            {
                value = -value;
            }

            // Split out the fractional part if we need to print a fraction
            double fractional = 0;

            if (slash != null)
            {
                if (improperFraction)
                {
                    fractional = value;
                    value      = 0;
                }
                else
                {
                    fractional = value % 1.0;
                    //noinspection SillyAssignment
                    value = (long)value;
                }
            }

            SortedList <CellNumberStringMod, object> mods = new SortedList <CellNumberStringMod, object>();
            StringBuilder output = new StringBuilder(desc);

            if (exponent != null)
            {
                WriteScientific(value, output, mods);
            }
            else if (improperFraction)
            {
                WriteFraction(value, null, fractional, output, mods);
            }
            else
            {
                StringBuilder result = new StringBuilder();
                //Formatter f = new Formatter(result);
                //f.Format(LOCALE, printfFmt, value);
                result.Append(value.ToString(printfFmt));
                if (numerator == null)
                {
                    WriteFractional(result, output);
                    Writeint(result, output, integerSpecials, mods, integerCommas);
                }
                else
                {
                    WriteFraction(value, result, fractional, output, mods);
                }
            }

            // Now strip out any remaining '#'s and add any pending text ...
            IEnumerator <Special> it         = specials.GetEnumerator();//.ListIterator();
            IEnumerator           Changes    = mods.Keys.GetEnumerator();
            CellNumberStringMod   nextChange = (Changes.MoveNext() ? (CellNumberStringMod)Changes.Current : null);
            int      adjust       = 0;
            BitArray deletedChars = new BitArray(1024); // records chars already deleted

            foreach (Special s in specials)
            {
                int adjustedPos = s.pos + adjust;
                if (!deletedChars[(s.pos)] && output[adjustedPos] == '#')
                {
                    output.Remove(adjustedPos, 1);
                    adjust--;
                    deletedChars.Set(s.pos, true);
                }
                while (nextChange != null && s == nextChange.GetSpecial())
                {
                    int lenBefore = output.Length;
                    int modPos    = s.pos + adjust;

                    switch (nextChange.Op)
                    {
                    case CellNumberStringMod.AFTER:
                        // ignore Adding a comma After a deleted char (which was a '#')
                        if (nextChange.ToAdd.Equals(",") && deletedChars.Get(s.pos))
                        {
                            break;
                        }
                        output.Insert(modPos + 1, nextChange.ToAdd);
                        break;

                    case CellNumberStringMod.BEFORE:
                        output.Insert(modPos, nextChange.ToAdd);
                        break;

                    case CellNumberStringMod.REPLACE:
                        // delete starting pos in original coordinates
                        int delPos = s.pos;
                        if (!nextChange.IsStartInclusive)
                        {
                            delPos++;
                            modPos++;
                        }

                        // Skip over anything already deleted
                        while (deletedChars.Get(delPos))
                        {
                            delPos++;
                            modPos++;
                        }

                        // delete end point in original
                        int delEndPos = nextChange.End.pos;
                        if (nextChange.IsEndInclusive)
                        {
                            delEndPos++;
                        }

                        // delete end point in current
                        int modEndPos = delEndPos + adjust;

                        if (modPos < modEndPos)
                        {
                            if (nextChange.ToAdd == "")
                            {
                                output.Remove(modPos, modEndPos - modPos);
                            }
                            else
                            {
                                char fillCh = nextChange.ToAdd[0];
                                for (int i = modPos; i < modEndPos; i++)
                                {
                                    output[i] = fillCh;
                                }
                            }
                            for (int k = delPos; k < delEndPos; k++)
                            {
                                deletedChars.Set(k, true);
                            }
                            //deletedChars.Set(delPos, delEndPos);
                        }
                        break;

                    default:
                        throw new InvalidOperationException("Unknown op: " + nextChange.Op);
                    }
                    adjust += output.Length - lenBefore;

                    if (Changes.MoveNext())
                    {
                        nextChange = (CellNumberStringMod)Changes.Current;
                    }
                    else
                    {
                        nextChange = null;
                    }
                }
            }

            // Finally, add it to the string
            if (negative)
            {
                toAppendTo.Append('-');
            }
            toAppendTo.Append(output);
        }