Explain the decimals
CJam, 32 bytes
l~1md@:X*mo'|*XSe]1$)NW$s,S*'-X*
Takes the precision first and the decimal second, separated by a space.
Run all test cases.
Explanation
l~ e# Read input and evaluate, pushing precision and decimal on the stack.
1md e# Divmod 1, separating the decimal into integer and fractional part.
@:X e# Pull up precision, store in X.
*mo e# Multiply precision by fractional part and round.
'|* e# Push that many vertical bars.
XSe] e# Pad with length X with spaces.
1$) e# Copy integer part and increment.
N e# Push linefeed.
W$ e# Copy integer part.
s, e# Get number of digits as length of string representation.
S* e# Push that many spaces, to indent the hyphens correctly.
'-X* e# Push X hyphens.
Mathematica, 119 bytes
a=ToString;b=Array;a[c=Floor@#]<>{b["|"&,d=Round[#2#~Mod~1]],b[" "&,#2-d],a[c+1],"
"," "&~b~IntegerLength@c,"-"&~b~#2}&
I tried... Testing:
In[1]:= a=ToString;b=Array;f=a[c=Floor@#]<>{b["|"&,d=Round[#2#~Mod~1]],b[" "&,#2-d],a[c+1],"\n"," "&~b~IntegerLength@c,"-"&~b~#2}&;
In[2]:= f[6.75, 4]
Out[2]= 6||| 7
----
In[3]:= f[10.5, 6]
Out[3]= 10||| 11
------
In[4]:= f[20.16, 12]
Out[4]= 20|| 21
------------
In[5]:= f[1.1, 12]
Out[5]= 1| 2
------------
In[6]:= f[5, 4]
Out[6]= 5 6
----
Java, 253 206 181 bytes
Saved 47 bytes thanks to @Kenney by inlining conditions and variables used once, and sorting out redundant variables.
Saved 25 bytes again thanks to @Kenney by inlining 2 loops with ternary operators.
Pure String Manipulation:
Inlined loops version (181 bytes):
String m(float f,int p){int g=(int)f,i=0;String h="",q=""+g;int c=q.length();for(;i<c+p;)h+=i++<c?" ":"-";for(i=c;i<p+c;)q+=i++<c+Math.round((f-g)*p)?"|":" ";return q+(g+1)+"\n"+h;}
4 loops version (206 bytes):
String m(float f,int p){int g=(int)f,i=0;String h="",q=""+g;int c=q.length();for(;i++<c;)h+=" ";for(;i<=c+p;i++)h+="-";for(i=c;i<c+Math.round((f-g)*p);i++)q+="|";for(;i++<p+c;)q+=" ";return q+(g+1)+"\n"+h;}
Ungolfed version:
String m(float f,int p){
//initialize some useful values, d is the number of pipes needed
int g=(int)f,d=Math.round((f-g)*p),i=0;
String h="",q=""+g;//append the floored value to the pipe string first
int c=q.length();
for(;i<c;i++)h+=" ";//pad hyphen string with spaces for alignment
for(++i;i<=c+p;i++)h+="-";//append hyphens
for(i=c;i<c+d;i++)q+="|";//append pipes
for(;i<p+c;i++)q+=" ";//append spaces for padding
return q+(g+1)+"\n"+h;}//concatenate the strings in order, separating the strings with a UNIX newline, and return it.
Working example here at ideone.com. The full program accepts STDIN input as
<float>,<precision>
.
NOTE: Java's Math.round(float)
rounds using RoundingMode.HALF_UP
as the default, which is the OP's required behaviour.
The output of the test cases provided was diff-matched to what the OP provided.